Overhaul how Config is passed around
authorAlex Crichton <alex@alexcrichton.com>
Wed, 14 Jan 2015 08:19:27 +0000 (00:19 -0800)
committerAlex Crichton <alex@alexcrichton.com>
Fri, 16 Jan 2015 16:45:07 +0000 (08:45 -0800)
This commit started out by moving the hash map of configuration values into
`Config` and then removing all calls to config::all_configs in favor of taking a
`&Config` argument. This initial step was taken to prevent reloading
configuration many times from disk, but it also provides a nice house for
configuration to be loaded from.

The commit snowballed into purging `MultiShell` as an argument all over the
place and passing around `Config` instead. Along the way a few other breaking
changes were made:

* The `config_for_key` and `config_list` subcommands have been removed. These
  commands are not ready to be stabilized and need some more work. In general
  the `cargo config` system needs to be cleaned out and built back up with a new
  interface, at which point these subcommands can return.
* The old and deprecated behavior of `cargo update foo` has been removed.

53 files changed:
src/bin/bench.rs
src/bin/build.rs
src/bin/cargo.rs
src/bin/clean.rs
src/bin/config_for_key.rs [deleted file]
src/bin/config_list.rs [deleted file]
src/bin/doc.rs
src/bin/fetch.rs
src/bin/generate_lockfile.rs
src/bin/git_checkout.rs
src/bin/help.rs
src/bin/locate_project.rs
src/bin/login.rs
src/bin/new.rs
src/bin/owner.rs
src/bin/package.rs
src/bin/pkgid.rs
src/bin/publish.rs
src/bin/read_manifest.rs
src/bin/run.rs
src/bin/search.rs
src/bin/test.rs
src/bin/update.rs
src/bin/verify_project.rs
src/bin/version.rs
src/bin/yank.rs
src/cargo/core/package_id_spec.rs
src/cargo/core/registry.rs
src/cargo/core/source.rs
src/cargo/lib.rs
src/cargo/ops/cargo_clean.rs
src/cargo/ops/cargo_compile.rs
src/cargo/ops/cargo_doc.rs
src/cargo/ops/cargo_fetch.rs
src/cargo/ops/cargo_generate_lockfile.rs
src/cargo/ops/cargo_new.rs
src/cargo/ops/cargo_package.rs
src/cargo/ops/cargo_pkgid.rs
src/cargo/ops/cargo_read_manifest.rs
src/cargo/ops/cargo_run.rs
src/cargo/ops/cargo_rustc/context.rs
src/cargo/ops/cargo_rustc/custom_build.rs
src/cargo/ops/cargo_rustc/job_queue.rs
src/cargo/ops/cargo_rustc/mod.rs
src/cargo/ops/cargo_test.rs
src/cargo/ops/registry.rs
src/cargo/sources/git/source.rs
src/cargo/sources/path.rs
src/cargo/sources/registry.rs
src/cargo/util/config.rs
src/cargo/util/toml.rs
tests/test_cargo.rs
tests/test_cargo_compile_git_deps.rs

index f8bf15ab90159ccb7d8c1e1d11f67855311229d6..7bd2100e593b06ce3f6b75f7dedab2733cd2aa38 100644 (file)
@@ -1,8 +1,7 @@
 use std::io::process::ExitStatus;
 
 use cargo::ops;
-use cargo::core::MultiShell;
-use cargo::util::{CliResult, CliError, Human};
+use cargo::util::{CliResult, CliError, Human, Config};
 use cargo::util::important_paths::{find_root_manifest_for_cwd};
 
 #[derive(RustcDecodable)]
@@ -49,16 +48,16 @@ see the `cargo help pkgid` command.
 Compilation can be customized with the `bench` profile in the manifest.
 ";
 
-pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
+pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
     let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path));
-    shell.set_verbose(options.flag_verbose);
+    config.shell().set_verbose(options.flag_verbose);
 
-    let mut ops = ops::TestOptions {
+    let ops = ops::TestOptions {
         name: options.flag_bench.as_ref().map(|s| s.as_slice()),
         no_run: options.flag_no_run,
         compile_opts: ops::CompileOptions {
             env: "bench",
-            shell: shell,
+            config: config,
             jobs: options.flag_jobs,
             target: options.flag_target.as_ref().map(|s| s.as_slice()),
             dev_deps: true,
@@ -70,7 +69,7 @@ pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>
         },
     };
 
-    let err = try!(ops::run_benches(&root, &mut ops,
+    let err = try!(ops::run_benches(&root, &ops,
                                     options.arg_args.as_slice()).map_err(|err| {
         CliError::from_boxed(err, 101)
     }));
index c6d35849b4bb5670b9aa0c485aeeb7c109f9485a..96a6be5b55c3fe28cf5d7f5fdb9cb4b8bd52bb8a 100644 (file)
@@ -1,10 +1,9 @@
 use std::os;
 
-use cargo::core::MultiShell;
 use cargo::ops::CompileOptions;
 use cargo::ops;
 use cargo::util::important_paths::{find_root_manifest_for_cwd};
-use cargo::util::{CliResult, CliError};
+use cargo::util::{CliResult, CliError, Config};
 
 #[derive(RustcDecodable)]
 struct Options {
@@ -47,9 +46,9 @@ the manifest. The default profile for this command is `dev`, but passing
 the --release flag will use the `release` profile instead.
 ";
 
-pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
+pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
     debug!("executing; cmd=cargo-build; args={:?}", os::args());
-    shell.set_verbose(options.flag_verbose);
+    config.shell().set_verbose(options.flag_verbose);
 
     let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path));
 
@@ -59,9 +58,9 @@ pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>
         "compile"
     };
 
-    let mut opts = CompileOptions {
+    let opts = CompileOptions {
         env: env,
-        shell: shell,
+        config: config,
         jobs: options.flag_jobs,
         target: options.flag_target.as_ref().map(|t| t.as_slice()),
         dev_deps: false,
@@ -72,7 +71,7 @@ pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>
         exec_engine: None,
     };
 
-    ops::compile(&root, &mut opts).map(|_| None).map_err(|err| {
+    ops::compile(&root, &opts).map(|_| None).map_err(|err| {
         CliError::from_boxed(err, 101)
     })
 }
index 4d922090bbc080fcfd3ec5914c1745a5ba4a4469..e0f9ca4eb2e334c1ddfd9cacd9409c60ab84fcce 100644 (file)
@@ -12,7 +12,7 @@ use std::io::process::{Command,InheritFd,ExitStatus,ExitSignal};
 
 use cargo::{execute_main_without_stdin, handle_error, shell};
 use cargo::core::MultiShell;
-use cargo::util::{CliError, CliResult, lev_distance};
+use cargo::util::{CliError, CliResult, lev_distance, Config};
 
 #[derive(RustcDecodable)]
 struct Flags {
@@ -56,8 +56,6 @@ macro_rules! each_subcommand{ ($mac:ident) => ({
     $mac!(bench);
     $mac!(build);
     $mac!(clean);
-    $mac!(config_for_key);
-    $mac!(config_list);
     $mac!(doc);
     $mac!(fetch);
     $mac!(generate_lockfile);
@@ -85,9 +83,9 @@ macro_rules! each_subcommand{ ($mac:ident) => ({
   because they are fundamental (and intertwined). Other commands can rely
   on this top-level information.
 */
-fn execute(flags: Flags, shell: &mut MultiShell) -> CliResult<Option<()>> {
+fn execute(flags: Flags, config: &Config) -> CliResult<Option<()>> {
     debug!("executing; cmd=cargo; args={:?}", os::args());
-    shell.set_verbose(flags.flag_verbose);
+    config.shell().set_verbose(flags.flag_verbose);
 
     if flags.flag_list {
         println!("Installed Commands:");
@@ -99,11 +97,11 @@ fn execute(flags: Flags, shell: &mut MultiShell) -> CliResult<Option<()>> {
 
     let (mut args, command) = match flags.arg_command.as_slice() {
         "" | "help" if flags.arg_args.len() == 0 => {
-            shell.set_verbose(true);
+            config.shell().set_verbose(true);
             let args = &[os::args()[0].clone(), "-h".to_string()];
-            let r = cargo::call_main_without_stdin(execute, shell, USAGE, args,
+            let r = cargo::call_main_without_stdin(execute, config, USAGE, args,
                                                    false);
-            cargo::process_executed(r, shell);
+            cargo::process_executed(r, &mut **config.shell());
             return Ok(None)
         }
         "help" if flags.arg_args[0].as_slice() == "-h" ||
@@ -118,18 +116,19 @@ fn execute(flags: Flags, shell: &mut MultiShell) -> CliResult<Option<()>> {
     macro_rules! cmd{ ($name:ident) => (
         if command.as_slice() == stringify!($name).replace("_", "-").as_slice() {
             mod $name;
-            shell.set_verbose(true);
-            let r = cargo::call_main_without_stdin($name::execute, shell,
+            config.shell().set_verbose(true);
+            let r = cargo::call_main_without_stdin($name::execute, config,
                                                    $name::USAGE,
                                                    args.as_slice(),
                                                    false);
-            cargo::process_executed(r, shell);
+            cargo::process_executed(r, &mut **config.shell());
             return Ok(None)
         }
     ) }
     each_subcommand!(cmd);
 
-    execute_subcommand(command.as_slice(), args.as_slice(), shell);
+    execute_subcommand(command.as_slice(), args.as_slice(),
+                       &mut **config.shell());
     Ok(None)
 }
 
@@ -153,7 +152,8 @@ fn execute_subcommand(cmd: &str, args: &[String], shell: &mut MultiShell) {
         Some(command) => command,
         None => {
             let msg = match find_closest(cmd) {
-                Some(closest) => format!("No such subcommand\n\n\tDid you mean `{}`?\n", closest),
+                Some(closest) => format!("No such subcommand\n\n\t\
+                                          Did you mean `{}`?\n", closest),
                 None => "No such subcommand".to_string()
             };
             return handle_error(CliError::new(msg, 127), shell)
index f5550c6cb778b155d16cd6dd85ffdd62ff5d9699..dcc013e46ba65f61288471793e5fba063a72f7a7 100644 (file)
@@ -1,8 +1,7 @@
 use std::os;
 
 use cargo::ops;
-use cargo::core::MultiShell;
-use cargo::util::{CliResult, CliError};
+use cargo::util::{CliResult, CliError, Config};
 use cargo::util::important_paths::{find_root_manifest_for_cwd};
 
 #[derive(RustcDecodable)]
@@ -32,17 +31,17 @@ given, then all packages' artifacts are removed. For more information on SPEC
 and its format, see the `cargo help pkgid` command.
 ";
 
-pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
-    shell.set_verbose(options.flag_verbose);
+pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
+    config.shell().set_verbose(options.flag_verbose);
     debug!("executing; cmd=cargo-clean; args={:?}", os::args());
 
     let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path));
-    let mut opts = ops::CleanOptions {
-        shell: shell,
+    let opts = ops::CleanOptions {
+        config: config,
         spec: options.flag_package.as_ref().map(|s| s.as_slice()),
         target: options.flag_target.as_ref().map(|s| s.as_slice()),
     };
-    ops::clean(&root, &mut opts).map(|_| None).map_err(|err| {
+    ops::clean(&root, &opts).map(|_| None).map_err(|err| {
       CliError::from_boxed(err, 101)
     })
 }
diff --git a/src/bin/config_for_key.rs b/src/bin/config_for_key.rs
deleted file mode 100644 (file)
index 4b10659..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-use std::os;
-use std::collections::HashMap;
-
-use cargo::core::MultiShell;
-use cargo::util::{CliResult, CliError, config};
-
-#[derive(RustcDecodable)]
-struct ConfigForKeyFlags {
-    flag_human: bool,
-    flag_key: String,
-}
-
-#[derive(RustcEncodable)]
-struct ConfigOut {
-    values: HashMap<String, config::ConfigValue>
-}
-
-pub const USAGE: &'static str = "
-Usage:
-    cargo config-for-key --human --key=<key>
-    cargo config-for-key -h | --help
-
-Options:
-    -h, --help          Print this message
-";
-
-pub fn execute(args: ConfigForKeyFlags,
-               _: &mut MultiShell) -> CliResult<Option<ConfigOut>> {
-    let cwd = try!(os::getcwd().map_err(|_|
-        CliError::new("Couldn't determine the current working directory", 1)));
-    let value = try!(config::get_config(cwd, args.flag_key.as_slice()).map_err(|_| {
-        CliError::new("Couldn't load configuration",  1)
-    }));
-
-    if args.flag_human {
-        println!("{:?}", value);
-        Ok(None)
-    } else {
-        let mut map = HashMap::new();
-        map.insert(args.flag_key.clone(), value);
-        Ok(Some(ConfigOut { values: map }))
-    }
-}
diff --git a/src/bin/config_list.rs b/src/bin/config_list.rs
deleted file mode 100644 (file)
index e267dbc..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-use std::os;
-use std::collections::HashMap;
-
-use cargo::core::MultiShell;
-use cargo::util::{CliResult, CliError, config};
-
-#[derive(RustcDecodable)]
-struct ConfigListFlags {
-    flag_human: bool,
-}
-
-#[derive(RustcEncodable)]
-struct ConfigOut {
-    values: HashMap<String, config::ConfigValue>
-}
-
-pub const USAGE: &'static str = "
-Usage:
-    cargo config-list --human
-    cargo config-list -h | --help
-
-Options:
-    -h, --help          Print this message
-";
-
-pub fn execute(args: ConfigListFlags,
-               _: &mut MultiShell) -> CliResult<Option<ConfigOut>> {
-    let cwd = try!(os::getcwd().map_err(|_|
-        CliError::new("Couldn't determine the current working directory", 1)));
-    let configs = try!(config::all_configs(cwd).map_err(|_|
-        CliError::new("Couldn't load configuration", 1)));
-
-    if args.flag_human {
-        for (key, value) in configs.iter() {
-            println!("{} = {:?}", key, value);
-        }
-        Ok(None)
-    } else {
-        Ok(Some(ConfigOut { values: configs }))
-    }
-}
index 11f9823a841c97149ee96799e7920c022188e0ad..d555676786c84fa3c8a31aa417ef46c540c7ef8a 100644 (file)
@@ -1,6 +1,5 @@
 use cargo::ops;
-use cargo::core::{MultiShell};
-use cargo::util::{CliResult, CliError};
+use cargo::util::{CliResult, CliError, Config};
 use cargo::util::important_paths::{find_root_manifest_for_cwd};
 
 #[derive(RustcDecodable)]
@@ -41,8 +40,8 @@ current package is documented. For more information on SPEC and its format, see
 the `cargo help pkgid` command.
 ";
 
-pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
-    shell.set_verbose(options.flag_verbose);
+pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
+    config.shell().set_verbose(options.flag_verbose);
 
     let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path));
 
@@ -51,7 +50,7 @@ pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>
         open_result: options.flag_open,
         compile_opts: ops::CompileOptions {
             env: if options.flag_no_deps {"doc"} else {"doc-all"},
-            shell: shell,
+            config: config,
             jobs: options.flag_jobs,
             target: None,
             dev_deps: false,
index 98e33f3b492c0ec830926ac6b4e5cd9716e24b3e..a5afbf239d5a4233afb2e122ab2ef4dd89e5fb78 100644 (file)
@@ -1,6 +1,5 @@
 use cargo::ops;
-use cargo::core::{MultiShell};
-use cargo::util::{CliResult, CliError};
+use cargo::util::{CliResult, CliError, Config};
 use cargo::util::important_paths::find_root_manifest_for_cwd;
 
 #[derive(RustcDecodable)]
@@ -30,10 +29,10 @@ If the lockfile is not available, then this is the equivalent of
 all updated.
 ";
 
-pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
-    shell.set_verbose(options.flag_verbose);
+pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
+    config.shell().set_verbose(options.flag_verbose);
     let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path));
-    try!(ops::fetch(&root, shell).map_err(|e| {
+    try!(ops::fetch(&root, config).map_err(|e| {
         CliError::from_boxed(e, 101)
     }));
     Ok(None)
index c2e50ddb452dc2995c80b8e23cc4286a35b8fd4b..a350ab63204550aa7caeca3dfa25902790734e0f 100644 (file)
@@ -1,8 +1,7 @@
 use std::os;
 
 use cargo::ops;
-use cargo::core::MultiShell;
-use cargo::util::{CliResult, CliError};
+use cargo::util::{CliResult, CliError, Config};
 use cargo::util::important_paths::find_root_manifest_for_cwd;
 
 #[derive(RustcDecodable)]
@@ -23,11 +22,11 @@ Options:
     -v, --verbose           Use verbose output
 ";
 
-pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
+pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
     debug!("executing; cmd=cargo-generate-lockfile; args={:?}", os::args());
-    shell.set_verbose(options.flag_verbose);
+    config.shell().set_verbose(options.flag_verbose);
     let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path));
 
-    ops::generate_lockfile(&root, shell)
+    ops::generate_lockfile(&root, config)
         .map(|_| None).map_err(|err| CliError::from_boxed(err, 101))
 }
index 3e825ec3c55a211e86b903f2e6f579436a94bc2f..3fa251821b325cf132ceed38a7c387b795dc9f15 100644 (file)
@@ -1,4 +1,3 @@
-use cargo::core::MultiShell;
 use cargo::core::source::{Source, SourceId, GitReference};
 use cargo::sources::git::{GitSource};
 use cargo::util::{Config, CliResult, CliError, human, ToUrl};
@@ -20,8 +19,8 @@ Options:
     -v, --verbose           Use verbose output
 ";
 
-pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
-    shell.set_verbose(options.flag_verbose);
+pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
+    config.shell().set_verbose(options.flag_verbose);
     let Options { flag_url: url, flag_reference: reference, .. } = options;
 
     let url = try!(url.as_slice().to_url().map_err(|e| {
@@ -33,10 +32,7 @@ pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>
     let reference = GitReference::Branch(reference.to_string());
     let source_id = SourceId::for_git(&url, reference);
 
-    let mut config = try!(Config::new(shell, None, None).map_err(|e| {
-        CliError::from_boxed(e, 1)
-    }));
-    let mut source = GitSource::new(&source_id, &mut config);
+    let mut source = GitSource::new(&source_id, config);
 
     try!(source.update().map_err(|e| {
         CliError::new(format!("Couldn't update {:?}: {:?}", source, e), 1)
index c21dbefebef096325e224e99f39d850104fcf2a2..f07a1cc669a1fe065bc777395c8cdb75148124aa 100644 (file)
@@ -1,5 +1,4 @@
-use cargo::core::MultiShell;
-use cargo::util::{CliResult, CliError};
+use cargo::util::{CliResult, CliError, Config};
 
 #[derive(RustcDecodable)]
 struct Options;
@@ -15,7 +14,7 @@ Options:
     -h, --help          Print this message
 ";
 
-pub fn execute(_: Options, _: &mut MultiShell) -> CliResult<Option<()>> {
+pub fn execute(_: Options, _: &Config) -> CliResult<Option<()>> {
     // This is a dummy command just so that `cargo help help` works.
     // The actual delegation of help flag to subcommands is handled by the
     // cargo command.
index 0644cb8649eecf625462f5a035f38cdf1e98c3e1..af2f45a60b26af8e5a17570dca04842ca13a972f 100644 (file)
@@ -1,5 +1,4 @@
-use cargo::core::MultiShell;
-use cargo::util::{CliResult, CliError, human, ChainError};
+use cargo::util::{CliResult, CliError, human, ChainError, Config};
 use cargo::util::important_paths::{find_root_manifest_for_cwd};
 
 #[derive(RustcDecodable)]
@@ -22,7 +21,7 @@ struct ProjectLocation {
 }
 
 pub fn execute(flags: LocateProjectFlags,
-               _: &mut MultiShell) -> CliResult<Option<ProjectLocation>> {
+               _: &Config) -> CliResult<Option<ProjectLocation>> {
     let root = try!(find_root_manifest_for_cwd(flags.flag_manifest_path));
 
     let string = try!(root.as_str()
index 6a164d4fe667f840ef7349e927e8979c5cdfc66a..bf3d707fd2a18476fc8d78ad60c6d6758ff1b836 100644 (file)
@@ -1,7 +1,7 @@
 use std::io;
 
 use cargo::ops;
-use cargo::core::{MultiShell, SourceId, Source};
+use cargo::core::{SourceId, Source};
 use cargo::sources::RegistrySource;
 use cargo::util::{CliResult, CliError, Config};
 
@@ -25,15 +25,14 @@ Options:
 
 ";
 
-pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
-    shell.set_verbose(options.flag_verbose);
+pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
+    config.shell().set_verbose(options.flag_verbose);
     let token = match options.arg_token.clone() {
         Some(token) => token,
         None => {
             let err = (|:| {
-                let config = try!(Config::new(shell, None, None));
-                let src = try!(SourceId::for_central());
-                let mut src = RegistrySource::new(&src, &config);
+                let src = try!(SourceId::for_central(config));
+                let mut src = RegistrySource::new(&src, config);
                 try!(src.update());
                 let config = try!(src.config());
                 let host = options.flag_host.clone().unwrap_or(config.api);
@@ -48,7 +47,7 @@ pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>
     };
 
     let token = token.as_slice().trim().to_string();
-    try!(ops::registry_login(shell, token).map_err(|e| {
+    try!(ops::registry_login(config, token).map_err(|e| {
         CliError::from_boxed(e, 101)
     }));
     Ok(None)
index e4c552643234a504898a02af9efc7a6cb602cb40..e2412d1cf69a5d5c9691d0c8f7f23678974dcd69 100644 (file)
@@ -1,8 +1,7 @@
 use std::os;
 
 use cargo::ops;
-use cargo::core::MultiShell;
-use cargo::util::{CliResult, CliError};
+use cargo::util::{CliResult, CliError, Config};
 
 #[derive(RustcDecodable)]
 struct Options {
@@ -28,9 +27,9 @@ Options:
     -v, --verbose       Use verbose output
 ";
 
-pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
+pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
     debug!("executing; cmd=cargo-new; args={:?}", os::args());
-    shell.set_verbose(options.flag_verbose);
+    config.shell().set_verbose(options.flag_verbose);
 
     let Options { flag_bin, arg_path, flag_vcs, .. } = options;
 
@@ -40,7 +39,7 @@ pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>
         bin: flag_bin,
     };
 
-    ops::new(opts, shell).map(|_| None).map_err(|err| {
+    ops::new(opts, config).map(|_| None).map_err(|err| {
         CliError::from_boxed(err, 101)
     })
 }
index b0bfcc3f67904da46a2ba98be53ad5661bc7b038..38edea893fa62bbbb524ce4075e804cac042767a 100644 (file)
@@ -1,6 +1,5 @@
 use cargo::ops;
-use cargo::core::MultiShell;
-use cargo::util::{CliResult, CliError};
+use cargo::util::{CliResult, CliError, Config};
 
 #[derive(RustcDecodable)]
 struct Options {
@@ -33,8 +32,8 @@ default). Note that owners of a package can upload new versions, yank old
 versions, and also modify the set of owners, so take caution!
 ";
 
-pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
-    shell.set_verbose(options.flag_verbose);
+pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
+    config.shell().set_verbose(options.flag_verbose);
     let opts = ops::OwnersOptions {
         krate: options.arg_crate,
         token: options.flag_token,
@@ -43,7 +42,7 @@ pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>
         to_remove: options.flag_remove,
         list: options.flag_list,
     };
-    try!(ops::modify_owners(shell, &opts).map_err(|e| {
+    try!(ops::modify_owners(config, &opts).map_err(|e| {
         CliError::from_boxed(e, 101)
     }));
     Ok(None)
index d529ba0873a0985993dfc3cfb5231ce33bc687af..444b114fbb3113fa807c1f454b6f148d51fe70d5 100644 (file)
@@ -1,6 +1,5 @@
 use cargo::ops;
-use cargo::core::{MultiShell};
-use cargo::util::{CliResult, CliError};
+use cargo::util::{CliResult, CliError, Config};
 use cargo::util::important_paths::find_root_manifest_for_cwd;
 
 #[derive(RustcDecodable)]
@@ -28,10 +27,10 @@ Options:
 
 ";
 
-pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
-    shell.set_verbose(options.flag_verbose);
+pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
+    config.shell().set_verbose(options.flag_verbose);
     let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path));
-    ops::package(&root, shell,
+    ops::package(&root, config,
                  !options.flag_no_verify,
                  options.flag_list,
                  !options.flag_no_metadata).map(|_| None).map_err(|err| {
index 53f09b099cf039f1ecc69fc2bd835a8a4a12398a..f0409b11f24d8de706efab42925a4f21e4abccf3 100644 (file)
@@ -1,6 +1,5 @@
 use cargo::ops;
-use cargo::core::MultiShell;
-use cargo::util::{CliResult, CliError};
+use cargo::util::{CliResult, CliError, Config};
 use cargo::util::important_paths::{find_root_manifest_for_cwd};
 
 #[derive(RustcDecodable)]
@@ -43,12 +42,12 @@ Example Package IDs
 ";
 
 pub fn execute(options: Options,
-               shell: &mut MultiShell) -> CliResult<Option<()>> {
-    shell.set_verbose(options.flag_verbose);
+               config: &Config) -> CliResult<Option<()>> {
+    config.shell().set_verbose(options.flag_verbose);
     let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path.clone()));
 
     let spec = options.arg_spec.as_ref().map(|s| s.as_slice());
-    let spec = try!(ops::pkgid(&root, spec, shell).map_err(|err| {
+    let spec = try!(ops::pkgid(&root, spec, config).map_err(|err| {
       CliError::from_boxed(err, 101)
     }));
     println!("{}", spec);
index 14327230600a4669a914db77c5b5a87293612f00..224c9a8b656927f9e21e11b544420b8329fadf32 100644 (file)
@@ -1,6 +1,5 @@
 use cargo::ops;
-use cargo::core::{MultiShell};
-use cargo::util::{CliResult, CliError};
+use cargo::util::{CliResult, CliError, Config};
 use cargo::util::important_paths::find_root_manifest_for_cwd;
 
 #[derive(RustcDecodable)]
@@ -28,8 +27,8 @@ Options:
 
 ";
 
-pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
-    shell.set_verbose(options.flag_verbose);
+pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
+    config.shell().set_verbose(options.flag_verbose);
     let Options {
         flag_token: token,
         flag_host: host,
@@ -39,7 +38,7 @@ pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>
     } = options;
 
     let root = try!(find_root_manifest_for_cwd(flag_manifest_path.clone()));
-    ops::publish(&root, shell, token, host, !no_verify).map(|_| None).map_err(|err| {
+    ops::publish(&root, config, token, host, !no_verify).map(|_| None).map_err(|err| {
         CliError::from_boxed(err, 101)
     })
 }
index fe8d88be0454e6e12019c86c285ebc5d44b2b142..4bf3303604ea17363895aa7d53e6504d1a010608 100644 (file)
@@ -1,5 +1,5 @@
-use cargo::core::{MultiShell, Package, Source};
-use cargo::util::{CliResult, CliError};
+use cargo::core::{Package, Source};
+use cargo::util::{CliResult, CliError, Config};
 use cargo::sources::{PathSource};
 
 #[derive(RustcDecodable)]
@@ -17,9 +17,9 @@ Options:
     -v, --verbose           Use verbose output
 ";
 
-pub fn execute(options: Options, _: &mut MultiShell) -> CliResult<Option<Package>> {
+pub fn execute(options: Options, config: &Config) -> CliResult<Option<Package>> {
     let path = Path::new(options.flag_manifest_path.as_slice());
-    let mut source = try!(PathSource::for_path(&path).map_err(|e| {
+    let mut source = try!(PathSource::for_path(&path, config).map_err(|e| {
         CliError::new(e.description(), 1)
     }));
 
index 42456d1a9b30ef9486402b6888726dc49acfc7ba..40e94f5782dd092b38fcd5a72cbcb39e8c597d8c 100644 (file)
@@ -1,9 +1,8 @@
 use std::io::process::ExitStatus;
 
 use cargo::ops;
-use cargo::core::{MultiShell};
 use cargo::core::manifest::TargetKind;
-use cargo::util::{CliResult, CliError, human};
+use cargo::util::{CliResult, CliError, human, Config};
 use cargo::util::important_paths::{find_root_manifest_for_cwd};
 
 #[derive(RustcDecodable)]
@@ -46,8 +45,8 @@ and `--example` specifies the example target to run. At most one of `--bin` or
 All of the trailing arguments are passed as to the binary to run.
 ";
 
-pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
-    shell.set_verbose(options.flag_verbose);
+pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
+    config.shell().set_verbose(options.flag_verbose);
     let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path));
 
     let env = match (options.flag_release, options.flag_example.is_some()) {
@@ -56,9 +55,9 @@ pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>
         (false, false) => "compile"
     };
 
-    let mut compile_opts = ops::CompileOptions {
+    let compile_opts = ops::CompileOptions {
         env: env,
-        shell: shell,
+        config: config,
         jobs: options.flag_jobs,
         target: options.flag_target.as_ref().map(|t| t.as_slice()),
         dev_deps: true,
@@ -80,7 +79,7 @@ pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>
     let err = try!(ops::run(&root,
                             target_kind,
                             name,
-                            &mut compile_opts,
+                            &compile_opts,
                             options.arg_args.as_slice()).map_err(|err| {
         CliError::from_boxed(err, 101)
     }));
index a973d14f65390b3595f5876a8388b708c7337d31..27901d6ea4ce4f1d276b801bb20020a2e6e7f96c 100644 (file)
@@ -1,6 +1,5 @@
 use cargo::ops;
-use cargo::core::{MultiShell};
-use cargo::util::{CliResult, CliError};
+use cargo::util::{CliResult, CliError, Config};
 
 #[derive(RustcDecodable)]
 struct Options {
@@ -21,15 +20,15 @@ Options:
     -v, --verbose           Use verbose output
 ";
 
-pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
-    shell.set_verbose(options.flag_verbose);
+pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
+    config.shell().set_verbose(options.flag_verbose);
     let Options {
         flag_host: host,
         arg_query: query,
         ..
     } = options;
 
-    ops::search(query.as_slice(), shell, host)
+    ops::search(query.as_slice(), config, host)
         .map(|_| None)
         .map_err(|err| CliError::from_boxed(err, 101))
 }
index a723210fd4e5b34292d4e24540732fd3b9694cfb..6d20f54f80c5cc4b96f0e6bbaf5f5fdcbe46d306 100644 (file)
@@ -1,8 +1,7 @@
 use std::io::process::ExitStatus;
 
 use cargo::ops;
-use cargo::core::MultiShell;
-use cargo::util::{CliResult, CliError, Human};
+use cargo::util::{CliResult, CliError, Human, Config};
 use cargo::util::important_paths::{find_root_manifest_for_cwd};
 
 #[derive(RustcDecodable)]
@@ -51,16 +50,16 @@ current package is tested. For more information on SPEC and its format, see the
 Compilation can be configured via the `test` profile in the manifest.
 ";
 
-pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
+pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
     let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path));
-    shell.set_verbose(options.flag_verbose);
+    config.shell().set_verbose(options.flag_verbose);
 
-    let mut ops = ops::TestOptions {
+    let ops = ops::TestOptions {
         name: options.flag_test.as_ref().map(|s| s.as_slice()),
         no_run: options.flag_no_run,
         compile_opts: ops::CompileOptions {
             env: "test",
-            shell: shell,
+            config: config,
             jobs: options.flag_jobs,
             target: options.flag_target.as_ref().map(|s| s.as_slice()),
             dev_deps: true,
@@ -72,7 +71,7 @@ pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>
         },
     };
 
-    let err = try!(ops::run_tests(&root, &mut ops,
+    let err = try!(ops::run_tests(&root, &ops,
                                   options.arg_args.as_slice()).map_err(|err| {
         CliError::from_boxed(err, 101)
     }));
index 005ea53fbc23ab84b8e5d80e09753d7847091e11..fa75506bcd253f2a03065d694cc396c46755e9fc 100644 (file)
@@ -1,13 +1,11 @@
 use std::os;
 
 use cargo::ops;
-use cargo::core::MultiShell;
-use cargo::util::{CliResult, CliError};
+use cargo::util::{CliResult, CliError, Config};
 use cargo::util::important_paths::find_root_manifest_for_cwd;
 
 #[derive(RustcDecodable)]
 struct Options {
-    arg_spec: Option<String>,
     flag_package: Option<String>,
     flag_aggressive: bool,
     flag_precise: Option<String>,
@@ -20,7 +18,6 @@ Update dependencies as recorded in the local lock file.
 
 Usage:
     cargo update [options]
-    cargo update [options] <spec>
 
 Options:
     -h, --help               Print this message
@@ -51,28 +48,21 @@ updated.
 For more information about package id specifications, see `cargo help pkgid`.
 ";
 
-pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
+pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
     debug!("executing; cmd=cargo-update; args={:?}", os::args());
-    shell.set_verbose(options.flag_verbose);
+    config.shell().set_verbose(options.flag_verbose);
     let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path));
 
-    let spec = if options.arg_spec.is_some() {
-        let _ = shell.warn("`cargo update foo` has been deprecated in favor \
-                            of `cargo update -p foo`. This functionality \
-                            will be removed in the future");
-        options.arg_spec.as_ref()
-    } else {
-        options.flag_package.as_ref()
-    };
+    let spec = options.flag_package.as_ref();
 
-    let mut update_opts = ops::UpdateOptions {
+    let update_opts = ops::UpdateOptions {
         aggressive: options.flag_aggressive,
         precise: options.flag_precise.as_ref().map(|s| s.as_slice()),
         to_update: spec.map(|s| s.as_slice()),
-        shell: shell,
+        config: config,
     };
 
-    ops::update_lockfile(&root, &mut update_opts)
+    ops::update_lockfile(&root, &update_opts)
         .map(|_| None).map_err(|err| CliError::from_boxed(err, 101))
 }
 
index 5445bc91958d7d7962040ca326b630b234651ddd..95fffab577df380a0e06d935a1d58af1c52297ee 100644 (file)
@@ -4,8 +4,7 @@ use std::collections::HashMap;
 use std::io::File;
 use std::os;
 
-use cargo::core::MultiShell;
-use cargo::util::CliResult;
+use cargo::util::{CliResult, Config};
 
 pub type Error = HashMap<String, String>;
 
@@ -26,9 +25,8 @@ Options:
     -v, --verbose           Use verbose output
 ";
 
-pub fn execute(args: Flags,
-               shell: &mut MultiShell) -> CliResult<Option<Error>> {
-    shell.set_verbose(args.flag_verbose);
+pub fn execute(args: Flags, config: &Config) -> CliResult<Option<Error>> {
+    config.shell().set_verbose(args.flag_verbose);
 
     let file = Path::new(args.flag_manifest_path);
     let contents = match File::open(&file).read_to_string() {
index ab212987e7e26cfa4919286fab018258d0a5c91d..e1bc0116f215fbf01b4308b44bc546a2b8a4c3cc 100644 (file)
@@ -1,8 +1,7 @@
 use std::os;
 
 use cargo;
-use cargo::core::MultiShell;
-use cargo::util::CliResult;
+use cargo::util::{CliResult, Config};
 
 #[derive(RustcDecodable)]
 struct Options;
@@ -16,7 +15,7 @@ Options:
     -v, --verbose           Use verbose output
 ";
 
-pub fn execute(_: Options, _: &mut MultiShell) -> CliResult<Option<()>> {
+pub fn execute(_: Options, _: &Config) -> CliResult<Option<()>> {
     debug!("executing; cmd=cargo-version; args={:?}", os::args());
 
     println!("{}", cargo::version());
index e79deabe74bdfadc4e14f9250666b8804faf6039..90cf677f104a6d5d843900b7e1f42bee1a7fcdf4 100644 (file)
@@ -1,6 +1,5 @@
 use cargo::ops;
-use cargo::core::MultiShell;
-use cargo::util::{CliResult, CliError};
+use cargo::util::{CliResult, CliError, Config};
 
 #[derive(RustcDecodable)]
 struct Options {
@@ -35,9 +34,9 @@ download the yanked version to use it. Cargo will, however, not allow any new
 crates to be locked to any yanked version.
 ";
 
-pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
-    shell.set_verbose(options.flag_verbose);
-    try!(ops::yank(shell,
+pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
+    config.shell().set_verbose(options.flag_verbose);
+    try!(ops::yank(config,
                    options.arg_crate,
                    options.flag_vers,
                    options.flag_token,
index d688b6e4570a69354970f0d5bf1842a39e3b08a3..ba028b5e8982f7b16f5048d4a5e7b2b331063616 100644 (file)
@@ -161,6 +161,7 @@ impl fmt::String for PackageIdSpec {
 mod tests {
     use core::{PackageId, SourceId};
     use super::{PackageIdSpec, url};
+    use url::Url;
     use semver::Version;
 
     #[test]
@@ -223,7 +224,8 @@ mod tests {
 
     #[test]
     fn matching() {
-        let sid = SourceId::for_central().unwrap();
+        let url = Url::parse("http://example.com").unwrap();
+        let sid = SourceId::for_registry(&url);
         let foo = PackageId::new("foo", "1.2.3", &sid).unwrap();
         let bar = PackageId::new("bar", "1.2.3", &sid).unwrap();
 
index 65f122943748096c859a9e48786bd5a4d2bc0f17..2ff375e3860beff1f3e76b59935b147b7c018022 100644 (file)
@@ -36,9 +36,9 @@ impl Registry for Vec<Summary> {
 /// `SourceMap` structure contained within which is a mapping of a `SourceId` to
 /// a `Source`. Each `Source` in the map has been updated (using network
 /// operations if necessary) and is ready to be queried for packages.
-pub struct PackageRegistry<'a> {
+pub struct PackageRegistry<'a, 'b: 'a> {
     sources: SourceMap<'a>,
-    config: &'a Config<'a>,
+    config: &'a Config<'b>,
 
     // A list of sources which are considered "overrides" which take precedent
     // when querying for packages.
@@ -71,8 +71,8 @@ enum Kind {
     Normal,
 }
 
-impl<'a> PackageRegistry<'a> {
-    pub fn new(config: &'a Config<'a>) -> PackageRegistry<'a> {
+impl<'a, 'b> PackageRegistry<'a, 'b> {
+    pub fn new(config: &'a Config<'b>) -> PackageRegistry<'a, 'b> {
         PackageRegistry {
             sources: SourceMap::new(),
             source_ids: HashMap::new(),
@@ -276,7 +276,7 @@ impl<'a> PackageRegistry<'a> {
     }
 }
 
-impl<'a> Registry for PackageRegistry<'a> {
+impl<'a, 'b> Registry for PackageRegistry<'a, 'b> {
     fn query(&mut self, dep: &Dependency) -> CargoResult<Vec<Summary>> {
         let overrides = try!(self.query_overrides(dep));
 
index 88ab4e1b032ae1f3a5253cc300e97a59443fe239..72252788c18be57bd0197594b3c95e1b86cfdd39 100644 (file)
@@ -176,8 +176,8 @@ impl SourceId {
     ///
     /// This is the main cargo registry by default, but it can be overridden in
     /// a `.cargo/config`.
-    pub fn for_central() -> CargoResult<SourceId> {
-        Ok(SourceId::for_registry(&try!(RegistrySource::url())))
+    pub fn for_central(config: &Config) -> CargoResult<SourceId> {
+        Ok(SourceId::for_registry(&try!(RegistrySource::url(config))))
     }
 
     pub fn get_url(&self) -> &Url { &self.inner.url }
@@ -201,7 +201,7 @@ impl SourceId {
                     Ok(p) => p,
                     Err(()) => panic!("path sources cannot be remote"),
                 };
-                Box::new(PathSource::new(&path, self)) as Box<Source>
+                Box::new(PathSource::new(&path, self, config)) as Box<Source>
             },
             Kind::Registry => {
                 Box::new(RegistrySource::new(self, config)) as Box<Source>
index 7c07021eb94021b9fd6974f7b67dbd64360ee5dc..cd3dc898a7984b9d5cb88d3a422802c1e13cd7ac 100644 (file)
@@ -33,7 +33,7 @@ use docopt::Docopt;
 use core::{Shell, MultiShell, ShellConfig};
 use term::color::{BLACK, RED};
 
-pub use util::{CargoError, CliError, CliResult, human};
+pub use util::{CargoError, CliError, CliResult, human, Config};
 
 macro_rules! some {
     ($e:expr) => (
@@ -58,7 +58,7 @@ pub mod sources;
 pub mod util;
 
 pub fn execute_main<T, U, V>(
-                        exec: fn(T, U, &mut MultiShell) -> CliResult<Option<V>>,
+                        exec: fn(T, U, &Config) -> CliResult<Option<V>>,
                         options_first: bool,
                         usage: &str)
     where V: Encodable, T: Decodable, U: Decodable
@@ -69,8 +69,8 @@ pub fn execute_main<T, U, V>(
 }
 
 pub fn call_main<T, U, V>(
-            exec: fn(T, U, &mut MultiShell) -> CliResult<Option<V>>,
-            shell: &mut MultiShell,
+            exec: fn(T, U, &Config) -> CliResult<Option<V>>,
+            shell: &Config,
             usage: &str,
             args: &[String],
             options_first: bool) -> CliResult<Option<V>>
@@ -83,7 +83,7 @@ pub fn call_main<T, U, V>(
 }
 
 pub fn execute_main_without_stdin<T, V>(
-                                      exec: fn(T, &mut MultiShell) -> CliResult<Option<V>>,
+                                      exec: fn(T, &Config) -> CliResult<Option<V>>,
                                       options_first: bool,
                                       usage: &str)
     where V: Encodable, T: Decodable
@@ -93,23 +93,9 @@ pub fn execute_main_without_stdin<T, V>(
     });
 }
 
-pub fn execute_main_with_args_and_without_stdin<T, V>(
-                                      exec: fn(T, &mut MultiShell) -> CliResult<Option<V>>,
-                                      options_first: bool,
-                                      usage: &str,
-                                      args: &[String])
-    where V: Encodable, T: Decodable
-{
-    let mut shell = shell(true);
-
-    process_executed(
-        call_main_without_stdin(exec, &mut shell, usage, args, options_first),
-        &mut shell)
-}
-
 pub fn call_main_without_stdin<T, V>(
-            exec: fn(T, &mut MultiShell) -> CliResult<Option<V>>,
-            shell: &mut MultiShell,
+            exec: fn(T, &Config) -> CliResult<Option<V>>,
+            shell: &Config,
             usage: &str,
             args: &[String],
             options_first: bool) -> CliResult<Option<V>>
@@ -120,15 +106,19 @@ pub fn call_main_without_stdin<T, V>(
 }
 
 fn process<V, F>(mut callback: F)
-    where F: FnMut(&[String], &mut MultiShell) -> CliResult<Option<V>>,
+    where F: FnMut(&[String], &Config) -> CliResult<Option<V>>,
           V: Encodable
 {
     let mut shell = shell(true);
-    process_executed(callback(os::args().as_slice(), &mut shell), &mut shell)
+    process_executed({
+        match Config::new(&mut shell) {
+            Ok(cfg) => callback(os::args().as_slice(), &cfg),
+            Err(e) => Err(CliError::from_boxed(e, 101)),
+        }
+    }, &mut shell)
 }
 
-pub fn process_executed<T>(result: CliResult<Option<T>>,
-                           shell: &mut MultiShell)
+pub fn process_executed<T>(result: CliResult<Option<T>>, shell: &mut MultiShell)
     where T: Encodable
 {
     match result {
index 45f1d4d172adbb6fab05d3cef962d4f8effa573d..592dbab56f184595fdd81fc056e65053f9cc7ee0 100644 (file)
@@ -1,21 +1,22 @@
 use std::default::Default;
 use std::io::fs::{self, PathExtensions};
 
-use core::{MultiShell, PackageSet};
+use core::PackageSet;
 use core::source::{Source, SourceMap};
 use sources::PathSource;
 use util::{CargoResult, human, ChainError, Config};
 use ops::{self, Layout, Context};
 
-pub struct CleanOptions<'a> {
+pub struct CleanOptions<'a, 'b: 'a> {
     pub spec: Option<&'a str>,
     pub target: Option<&'a str>,
-    pub shell: &'a mut MultiShell,
+    pub config: &'a Config<'b>,
 }
 
 /// Cleans the project from build artifacts.
-pub fn clean(manifest_path: &Path, opts: &mut CleanOptions) -> CargoResult<()> {
-    let mut src = try!(PathSource::for_path(&manifest_path.dir_path()));
+pub fn clean(manifest_path: &Path, opts: &CleanOptions) -> CargoResult<()> {
+    let mut src = try!(PathSource::for_path(&manifest_path.dir_path(),
+                                            opts.config));
     try!(src.update());
     let root = try!(src.get_root_package());
     let manifest = root.get_manifest();
@@ -37,9 +38,8 @@ pub fn clean(manifest_path: &Path, opts: &mut CleanOptions) -> CargoResult<()> {
     let pkgid = try!(resolve.query(spec));
 
     // Translate the PackageId to a Package
-    let mut cfg = try!(Config::new(opts.shell, None, None));
     let pkg = {
-        let mut source = pkgid.get_source_id().load(&mut cfg);
+        let mut source = pkgid.get_source_id().load(opts.config);
         try!(source.update());
         (try!(source.get(&[pkgid.clone()]))).into_iter().next().unwrap()
     };
@@ -48,7 +48,7 @@ pub fn clean(manifest_path: &Path, opts: &mut CleanOptions) -> CargoResult<()> {
     // filenames and such
     let srcs = SourceMap::new();
     let pkgs = PackageSet::new(&[]);
-    let cx = try!(Context::new("compile", &resolve, &srcs, &pkgs, &mut cfg,
+    let cx = try!(Context::new("compile", &resolve, &srcs, &pkgs, opts.config,
                                Layout::at(root.get_absolute_target_dir()),
                                None, &pkg, Default::default()));
 
index 4da2ad92b8ec5ba7c266c0487ab558444013674b..ec002d943c6671a5d8b673d60ddc22a41f03272f 100644 (file)
@@ -28,7 +28,7 @@ use std::default::Default;
 use std::sync::Arc;
 
 use core::registry::PackageRegistry;
-use core::{MultiShell, Source, SourceId, PackageSet, Package, Target, PackageId};
+use core::{Source, SourceId, PackageSet, Package, Target, PackageId};
 use core::resolver::Method;
 use ops::{self, BuildOutput, ExecEngine};
 use sources::{PathSource};
@@ -36,9 +36,9 @@ use util::config::{Config, ConfigValue};
 use util::{CargoResult, config, internal, human, ChainError, profile};
 
 /// Contains informations about how a package should be compiled.
-pub struct CompileOptions<'a> {
+pub struct CompileOptions<'a, 'b: 'a> {
     pub env: &'a str,
-    pub shell: &'a mut MultiShell,
+    pub config: &'a Config<'b>,
     /// Number of concurrent jobs to use.
     pub jobs: Option<u32>,
     /// The target platform to compile for (example: `i686-unknown-linux-gnu`).
@@ -53,11 +53,12 @@ pub struct CompileOptions<'a> {
 }
 
 pub fn compile(manifest_path: &Path,
-               options: &mut CompileOptions)
+               options: &CompileOptions)
                -> CargoResult<ops::Compilation> {
     log!(4, "compile; manifest-path={}", manifest_path.display());
 
-    let mut source = try!(PathSource::for_path(&manifest_path.dir_path()));
+    let mut source = try!(PathSource::for_path(&manifest_path.dir_path(),
+                                               options.config));
     try!(source.update());
 
     // TODO: Move this into PathSource
@@ -65,16 +66,16 @@ pub fn compile(manifest_path: &Path,
     debug!("loaded package; package={}", package);
 
     for key in package.get_manifest().get_warnings().iter() {
-        try!(options.shell.warn(key))
+        try!(options.config.shell().warn(key))
     }
     compile_pkg(&package, options)
 }
 
-pub fn compile_pkg(package: &Package, options: &mut CompileOptions)
+pub fn compile_pkg(package: &Package, options: &CompileOptions)
                    -> CargoResult<ops::Compilation> {
-    let CompileOptions { env, ref mut shell, jobs, target, spec,
+    let CompileOptions { env, config, jobs, target, spec,
                          dev_deps, features, no_default_features,
-                         lib_only, ref mut exec_engine } = *options;
+                         lib_only, ref exec_engine } = *options;
 
     let target = target.map(|s| s.to_string());
     let features = features.iter().flat_map(|s| {
@@ -85,15 +86,16 @@ pub fn compile_pkg(package: &Package, options: &mut CompileOptions)
         return Err(human("features cannot be modified when the main package \
                           is not being built"))
     }
+    if jobs == Some(0) {
+        return Err(human("jobs must be at least 1"))
+    }
 
-    let user_configs = try!(config::all_configs(try!(os::getcwd())));
-    let override_ids = try!(source_ids_from_config(&user_configs,
+    let override_ids = try!(source_ids_from_config(config,
                                                    package.get_root()));
-    let config = try!(Config::new(*shell, jobs, target.clone()));
 
     let (packages, resolve_with_overrides, sources) = {
         let rustc_host = config.rustc_host().to_string();
-        let mut registry = PackageRegistry::new(&config);
+        let mut registry = PackageRegistry::new(config);
 
         // First, resolve the package's *listed* dependencies, as well as
         // downloading and updating all remotes and such.
@@ -147,21 +149,22 @@ pub fn compile_pkg(package: &Package, options: &mut CompileOptions)
 
     let ret = {
         let _p = profile::start("compiling");
-        let lib_overrides = try!(scrape_build_config(&config, &user_configs));
+        let lib_overrides = try!(scrape_build_config(config, jobs, target));
 
         try!(ops::compile_targets(env.as_slice(), targets.as_slice(), to_build,
                                   &PackageSet::new(packages.as_slice()),
                                   &resolve_with_overrides, &sources,
-                                  &config, lib_overrides, exec_engine.clone()))
+                                  config, lib_overrides, exec_engine.clone()))
     };
 
     return Ok(ret);
 }
 
-fn source_ids_from_config(configs: &HashMap<String, config::ConfigValue>,
-                          cur_path: Path) -> CargoResult<Vec<SourceId>> {
-    debug!("loaded config; configs={:?}", configs);
+fn source_ids_from_config(config: &Config, cur_path: Path)
+                          -> CargoResult<Vec<SourceId>> {
 
+    let configs = try!(config.values());
+    debug!("loaded config; configs={:?}", configs);
     let config_paths = match configs.get("paths") {
         Some(cfg) => cfg,
         None => return Ok(Vec::new())
@@ -183,21 +186,27 @@ fn source_ids_from_config(configs: &HashMap<String, config::ConfigValue>,
 }
 
 fn scrape_build_config(config: &Config,
-                       configs: &HashMap<String, config::ConfigValue>)
-                       -> CargoResult<ops::BuildConfig> {
-    let target = match configs.get("target") {
-        None => return Ok(Default::default()),
+                       jobs: Option<u32>,
+                       target: Option<String>) -> CargoResult<ops::BuildConfig> {
+    let configs = try!(config.values());
+    let mut base = ops::BuildConfig {
+        jobs: jobs.unwrap_or(os::num_cpus() as u32),
+        requested_target: target.clone(),
+        ..Default::default()
+    };
+    let target_config = match configs.get("target") {
+        None => return Ok(base),
         Some(target) => try!(target.table().chain_error(|| {
             internal("invalid configuration for the key `target`")
         })),
     };
 
-    let host = try!(scrape_target_config(target, config.rustc_host()));
-    let target = match config.target() {
-        Some(triple) => try!(scrape_target_config(target, triple)),
-        None => host.clone(),
+    base.host = try!(scrape_target_config(target_config, config.rustc_host()));
+    base.target = match target.as_ref() {
+        Some(triple) => try!(scrape_target_config(target_config, &triple[])),
+        None => base.host.clone(),
     };
-    Ok(ops::BuildConfig { host: host, target: target })
+    Ok(base)
 }
 
 fn scrape_target_config(target: &HashMap<String, config::ConfigValue>,
index 2e7831440716adadf1a5517123133fc2fd75213a..251e9e26f5742cfdbe0ee3ec15330015eaf23484 100644 (file)
@@ -8,15 +8,16 @@ use sources::PathSource;
 use std::io::process::Command;
 use util::{CargoResult, human};
 
-pub struct DocOptions<'a> {
+pub struct DocOptions<'a, 'b: 'a> {
     pub all: bool,
     pub open_result: bool,
-    pub compile_opts: ops::CompileOptions<'a>,
+    pub compile_opts: ops::CompileOptions<'a, 'b>,
 }
 
 pub fn doc(manifest_path: &Path,
-           options: &mut DocOptions) -> CargoResult<()> {
-    let mut source = try!(PathSource::for_path(&manifest_path.dir_path()));
+           options: &DocOptions) -> CargoResult<()> {
+    let mut source = try!(PathSource::for_path(&manifest_path.dir_path(),
+                                               options.compile_opts.config));
     try!(source.update());
     let package = try!(source.get_root_package());
 
@@ -40,7 +41,7 @@ pub fn doc(manifest_path: &Path,
         }
     }
 
-    try!(ops::compile(manifest_path, &mut options.compile_opts));
+    try!(ops::compile(manifest_path, &options.compile_opts));
 
     if options.open_result {
         let name = match options.compile_opts.spec {
index 4c4cb0ebffeb31a9c86fbcc9190f29414ac74ea3..44ef632bfd21431b8fa56b3c9162a661b1c5b76c 100644 (file)
@@ -1,4 +1,3 @@
-use core::MultiShell;
 use core::registry::PackageRegistry;
 use core::source::Source;
 use ops;
@@ -6,14 +5,13 @@ use sources::PathSource;
 use util::{CargoResult, Config};
 
 /// Executes `cargo fetch`.
-pub fn fetch(manifest_path: &Path,
-             shell: &mut MultiShell) -> CargoResult<()> {
-    let mut source = try!(PathSource::for_path(&manifest_path.dir_path()));
+pub fn fetch(manifest_path: &Path, config: &Config) -> CargoResult<()> {
+    let mut source = try!(PathSource::for_path(&manifest_path.dir_path(),
+                                               config));
     try!(source.update());
     let package = try!(source.get_root_package());
 
-    let mut config = try!(Config::new(shell, None, None));
-    let mut registry = PackageRegistry::new(&mut config);
+    let mut registry = PackageRegistry::new(config);
     try!(ops::resolve_pkg(&mut registry, &package));
     Ok(())
 }
index 47d987f9f8dea42aa80708f35717c60efe4dfe94..91de743272cb1d03614819e97e9d8be45051aacd 100644 (file)
@@ -2,28 +2,27 @@ use std::collections::HashSet;
 
 use core::PackageId;
 use core::registry::PackageRegistry;
-use core::{MultiShell, Source, Resolve};
+use core::{Source, Resolve};
 use core::resolver::Method;
 use ops;
 use sources::{PathSource};
 use util::config::{Config};
 use util::{CargoResult, human};
 
-pub struct UpdateOptions<'a> {
-    pub shell: &'a mut MultiShell,
+pub struct UpdateOptions<'a, 'b: 'a> {
+    pub config: &'a Config<'b>,
     pub to_update: Option<&'a str>,
     pub precise: Option<&'a str>,
     pub aggressive: bool,
 }
 
-pub fn generate_lockfile(manifest_path: &Path,
-                         shell: &mut MultiShell)
+pub fn generate_lockfile(manifest_path: &Path, config: &Config)
                          -> CargoResult<()> {
-    let mut source = try!(PathSource::for_path(&manifest_path.dir_path()));
+    let mut source = try!(PathSource::for_path(&manifest_path.dir_path(),
+                                               config));
     try!(source.update());
     let package = try!(source.get_root_package());
-    let mut config = try!(Config::new(shell, None, None));
-    let mut registry = PackageRegistry::new(&mut config);
+    let mut registry = PackageRegistry::new(config);
     let resolve = try!(ops::resolve_with_previous(&mut registry, &package,
                                                   Method::Everything,
                                                   None, None));
@@ -32,8 +31,9 @@ pub fn generate_lockfile(manifest_path: &Path,
 }
 
 pub fn update_lockfile(manifest_path: &Path,
-                       opts: &mut UpdateOptions) -> CargoResult<()> {
-    let mut source = try!(PathSource::for_path(&manifest_path.dir_path()));
+                       opts: &UpdateOptions) -> CargoResult<()> {
+    let mut source = try!(PathSource::for_path(&manifest_path.dir_path(),
+                                               opts.config));
     try!(source.update());
     let package = try!(source.get_root_package());
 
@@ -47,8 +47,7 @@ pub fn update_lockfile(manifest_path: &Path,
                           simultaneously"))
     }
 
-    let mut config = try!(Config::new(opts.shell, None, None));
-    let mut registry = PackageRegistry::new(&mut config);
+    let mut registry = PackageRegistry::new(opts.config);
     let mut to_avoid = HashSet::new();
 
     match opts.to_update {
index 26ddad9b3d947924bce06b0128abff4cdd5081e2..9649fffd44907961fb7443fdfa1a3f25fbedf798 100644 (file)
@@ -4,10 +4,10 @@ use std::io::fs::PathExtensions;
 
 use rustc_serialize::{Decodable, Decoder};
 
-use git2::Config;
+use git2::Config as GitConfig;
 
-use util::{GitRepo, HgRepo, CargoResult, human, ChainError, config, internal};
-use core::shell::MultiShell;
+use util::{GitRepo, HgRepo, CargoResult, human, ChainError, internal};
+use util::Config;
 
 #[derive(Copy, Show, PartialEq)]
 pub enum VersionControl { Git, Hg, NoVcs }
@@ -38,8 +38,8 @@ struct CargoNewConfig {
     version_control: Option<VersionControl>,
 }
 
-pub fn new(opts: NewOptions, _shell: &mut MultiShell) -> CargoResult<()> {
-    let path = try!(os::getcwd()).join(opts.path);
+pub fn new(opts: NewOptions, config: &Config) -> CargoResult<()> {
+    let path = config.cwd().join(opts.path);
     if path.exists() {
         return Err(human(format!("Destination `{}` already exists",
                                  path.display())))
@@ -51,7 +51,7 @@ pub fn new(opts: NewOptions, _shell: &mut MultiShell) -> CargoResult<()> {
         return Err(human(format!("Invalid character `{}` in crate name: `{}`",
                                  c, name).as_slice()));
     }
-    mk(&path, name, &opts).chain_error(|| {
+    mk(config, &path, name, &opts).chain_error(|| {
         human(format!("Failed to create project `{}` at `{}`",
                       name, path.display()))
     })
@@ -61,8 +61,9 @@ fn existing_vcs_repo(path: &Path) -> bool {
     GitRepo::discover(path).is_ok() || HgRepo::discover(path).is_ok()
 }
 
-fn mk(path: &Path, name: &str, opts: &NewOptions) -> CargoResult<()> {
-    let cfg = try!(global_config());
+fn mk(config: &Config, path: &Path, name: &str,
+      opts: &NewOptions) -> CargoResult<()> {
+    let cfg = try!(global_config(config));
     let mut ignore = "/target\n".to_string();
     let in_existing_vcs_repo = existing_vcs_repo(&path.dir_path());
     if !opts.bin {
@@ -129,7 +130,7 @@ fn it_works() {
 }
 
 fn discover_author() -> CargoResult<(String, Option<String>)> {
-    let git_config = Config::open_default().ok();
+    let git_config = GitConfig::open_default().ok();
     let git_config = git_config.as_ref();
     let name = git_config.and_then(|g| g.get_str("user.name").ok())
                          .map(|s| s.to_string())
@@ -151,8 +152,8 @@ fn discover_author() -> CargoResult<(String, Option<String>)> {
     Ok((name, email))
 }
 
-fn global_config() -> CargoResult<CargoNewConfig> {
-    let user_configs = try!(config::all_configs(try!(os::getcwd())));
+fn global_config(config: &Config) -> CargoResult<CargoNewConfig> {
+    let user_configs = try!(config.values());
     let mut cfg = CargoNewConfig {
         name: None,
         email: None,
index 0ff3d8760fdfed01b7f47be6c1a5888900893967..e158ccd31256cc8531819a71abf13068942dc0e9 100644 (file)
@@ -7,9 +7,9 @@ use flate2::{GzBuilder, BestCompression};
 use flate2::reader::GzDecoder;
 
 use core::source::{Source, SourceId};
-use core::{Package, MultiShell};
+use core::Package;
 use sources::PathSource;
-use util::{CargoResult, human, internal, ChainError};
+use util::{CargoResult, human, internal, ChainError, Config};
 use ops;
 
 struct Bomb { path: Option<Path> }
@@ -24,16 +24,17 @@ impl Drop for Bomb {
 }
 
 pub fn package(manifest_path: &Path,
-               shell: &mut MultiShell,
+               config: &Config,
                verify: bool,
                list: bool,
                metadata: bool) -> CargoResult<Option<Path>> {
-    let mut src = try!(PathSource::for_path(&manifest_path.dir_path()));
+    let mut src = try!(PathSource::for_path(&manifest_path.dir_path(),
+                                            config));
     try!(src.update());
     let pkg = try!(src.get_root_package());
 
     if metadata {
-        try!(check_metadata(&pkg, shell));
+        try!(check_metadata(&pkg, config));
     }
 
     if list {
@@ -55,12 +56,12 @@ pub fn package(manifest_path: &Path,
 
     let mut bomb = Bomb { path: Some(dst.clone()) };
 
-    try!(shell.status("Packaging", pkg.get_package_id().to_string()));
-    try!(tar(&pkg, &src, shell, &dst).chain_error(|| {
+    try!(config.shell().status("Packaging", pkg.get_package_id().to_string()));
+    try!(tar(&pkg, &src, config, &dst).chain_error(|| {
         human("failed to prepare local package for uploading")
     }));
     if verify {
-        try!(run_verify(&pkg, shell, &dst).chain_error(|| {
+        try!(run_verify(config, &pkg, &dst).chain_error(|| {
             human("failed to verify package tarball")
         }))
     }
@@ -69,7 +70,7 @@ pub fn package(manifest_path: &Path,
 
 // check that the package has some piece of metadata that a human can
 // use to tell what the package is about.
-fn check_metadata(pkg: &Package, shell: &mut MultiShell) -> CargoResult<()> {
+fn check_metadata(pkg: &Package, config: &Config) -> CargoResult<()> {
     let md = pkg.get_manifest().get_metadata();
 
     let mut missing = vec![];
@@ -93,7 +94,7 @@ fn check_metadata(pkg: &Package, shell: &mut MultiShell) -> CargoResult<()> {
         }
         things.push_str(missing.last().unwrap().as_slice());
 
-        try!(shell.warn(
+        try!(config.shell().warn(
             format!("warning: manifest has no {things}. \
                     See http://doc.crates.io/manifest.html#package-metadata for more info.",
                     things = things).as_slice()))
@@ -101,7 +102,7 @@ fn check_metadata(pkg: &Package, shell: &mut MultiShell) -> CargoResult<()> {
     Ok(())
 }
 
-fn tar(pkg: &Package, src: &PathSource, shell: &mut MultiShell,
+fn tar(pkg: &Package, src: &PathSource, config: &Config,
        dst: &Path) -> CargoResult<()> {
 
     if dst.exists() {
@@ -128,7 +129,7 @@ fn tar(pkg: &Package, src: &PathSource, shell: &mut MultiShell,
                           relative.display()))
         }));
         let mut file = try!(File::open(file));
-        try!(shell.verbose(|shell| {
+        try!(config.shell().verbose(|shell| {
             shell.status("Archiving", relative.as_slice())
         }));
         let path = format!("{}-{}{}{}", pkg.get_name(),
@@ -141,9 +142,9 @@ fn tar(pkg: &Package, src: &PathSource, shell: &mut MultiShell,
     Ok(())
 }
 
-fn run_verify(pkg: &Package, shell: &mut MultiShell, tar: &Path)
+fn run_verify(config: &Config, pkg: &Package, tar: &Path)
               -> CargoResult<()> {
-    try!(shell.status("Verifying", pkg));
+    try!(config.shell().status("Verifying", pkg));
 
     let f = try!(GzDecoder::new(try!(File::open(tar))));
     let dst = pkg.get_root().join(format!("target/package/{}-{}",
@@ -158,7 +159,7 @@ fn run_verify(pkg: &Package, shell: &mut MultiShell, tar: &Path)
     // When packages are uploaded to the registry, all path dependencies are
     // implicitly converted to registry-based dependencies, so we rewrite those
     // dependencies here.
-    let registry = try!(SourceId::for_central());
+    let registry = try!(SourceId::for_central(config));
     let new_summary = pkg.get_summary().clone().map_dependencies(|d| {
         if !d.get_source_id().is_path() { return d }
         d.source_id(registry.clone())
@@ -170,9 +171,9 @@ fn run_verify(pkg: &Package, shell: &mut MultiShell, tar: &Path)
                                pkg.get_package_id().get_source_id());
 
     // Now that we've rewritten all our path dependencies, compile it!
-    try!(ops::compile_pkg(&new_pkg, &mut ops::CompileOptions {
+    try!(ops::compile_pkg(&new_pkg, &ops::CompileOptions {
         env: "compile",
-        shell: shell,
+        config: config,
         jobs: None,
         target: None,
         dev_deps: false,
index 3b39bb0e7d78853e587401ca08bd31cc22b4da86..f32484457530697ee186c805fa60d3ce7f8a6d1f 100644 (file)
@@ -1,12 +1,13 @@
 use ops;
-use core::{MultiShell, Source, PackageIdSpec};
+use core::{Source, PackageIdSpec};
 use sources::{PathSource};
-use util::{CargoResult, human};
+use util::{CargoResult, human, Config};
 
 pub fn pkgid(manifest_path: &Path,
              spec: Option<&str>,
-             _shell: &mut MultiShell) -> CargoResult<PackageIdSpec> {
-    let mut source = try!(PathSource::for_path(&manifest_path.dir_path()));
+             config: &Config) -> CargoResult<PackageIdSpec> {
+    let mut source = try!(PathSource::for_path(&manifest_path.dir_path(),
+                                               config));
     try!(source.update());
     let package = try!(source.get_root_package());
 
index 3c5f5b603a1939323f6fd7dae4dc4cdce5122ab8..9314736d936bb8d235c514395c87f81b80f1ccfc 100644 (file)
@@ -1,37 +1,38 @@
 use std::collections::HashSet;
-use std::io::{self, File, fs};
+use std::error::FromError;
 use std::io::fs::PathExtensions;
+use std::io::{self, File, fs};
 
 use core::{Package,Manifest,SourceId};
-use util::{self, CargoResult, human};
+use util::{self, CargoResult, human, Config};
 use util::important_paths::find_project_manifest_exact;
 use util::toml::{Layout, project_layout};
-use std::error::FromError;
 
-pub fn read_manifest(contents: &[u8], layout: Layout, source_id: &SourceId)
+pub fn read_manifest(contents: &[u8], layout: Layout, source_id: &SourceId,
+                     config: &Config)
                      -> CargoResult<(Manifest, Vec<Path>)> {
     let root = layout.root.clone();
-    util::toml::to_manifest(contents, source_id, layout).map_err(|e| {
+    util::toml::to_manifest(contents, source_id, layout, config).map_err(|e| {
         human(format!("failed to parse manifest at `{:?}`\n{}",
                       root.join("Cargo.toml"), e))
     })
 }
 
-pub fn read_package(path: &Path, source_id: &SourceId)
-    -> CargoResult<(Package, Vec<Path>)> {
+pub fn read_package(path: &Path, source_id: &SourceId, config: &Config)
+                    -> CargoResult<(Package, Vec<Path>)> {
     log!(5, "read_package; path={}; source-id={}", path.display(), source_id);
     let mut file = try!(File::open(path));
     let data = try!(file.read_to_end());
 
     let layout = project_layout(&path.dir_path());
     let (manifest, nested) =
-        try!(read_manifest(data.as_slice(), layout, source_id));
+        try!(read_manifest(data.as_slice(), layout, source_id, config));
 
     Ok((Package::new(manifest, path, source_id), nested))
 }
 
-pub fn read_packages(path: &Path,
-                     source_id: &SourceId) -> CargoResult<Vec<Package>> {
+pub fn read_packages(path: &Path, source_id: &SourceId, config: &Config)
+                     -> CargoResult<Vec<Package>> {
     let mut all_packages = HashSet::new();
     let mut visited = HashSet::<Path>::new();
 
@@ -52,7 +53,7 @@ pub fn read_packages(path: &Path,
         }
 
         if has_manifest(dir) {
-            try!(read_nested_packages(dir, &mut all_packages, source_id,
+            try!(read_nested_packages(dir, &mut all_packages, source_id, config,
                                       &mut visited));
         }
         Ok(true)
@@ -104,12 +105,13 @@ fn has_manifest(path: &Path) -> bool {
 fn read_nested_packages(path: &Path,
                         all_packages: &mut HashSet<Package>,
                         source_id: &SourceId,
+                        config: &Config,
                         visited: &mut HashSet<Path>) -> CargoResult<()> {
     if !visited.insert(path.clone()) { return Ok(()) }
 
     let manifest = try!(find_project_manifest_exact(path, "Cargo.toml"));
 
-    let (pkg, nested) = try!(read_package(&manifest, source_id));
+    let (pkg, nested) = try!(read_package(&manifest, source_id, config));
     all_packages.insert(pkg);
 
     // Registry sources are not allowed to have `path=` dependencies because
@@ -117,7 +119,7 @@ fn read_nested_packages(path: &Path,
     if !source_id.is_registry() {
         for p in nested.iter() {
             try!(read_nested_packages(&path.join(p), all_packages, source_id,
-                                      visited));
+                                      config, visited));
         }
     }
 
index 772828c23c868b48a4393ebe1c314b2871cfbd80..0ef3986a9f1ff26364958cda266dde918fe19263 100644 (file)
@@ -9,9 +9,10 @@ use sources::PathSource;
 pub fn run(manifest_path: &Path,
            target_kind: TargetKind,
            name: Option<String>,
-           options: &mut ops::CompileOptions,
+           options: &ops::CompileOptions,
            args: &[String]) -> CargoResult<Option<ProcessError>> {
-    let mut src = try!(PathSource::for_path(&manifest_path.dir_path()));
+    let config = options.config;
+    let mut src = try!(PathSource::for_path(&manifest_path.dir_path(), config));
     try!(src.update());
     let root = try!(src.get_root_package());
     let env = options.env;
@@ -56,6 +57,6 @@ pub fn run(manifest_path: &Path,
                               .args(args)
                               .cwd(try!(os::getcwd()));
 
-    try!(options.shell.status("Running", process.to_string()));
+    try!(config.shell().status("Running", process.to_string()));
     Ok(process.exec().err())
 }
index 41dca8dbd723bdc4575d8e0a516a4bc22795ae06..1a6c08c0356c3a02680cf8c2f3cdc47755532f2b 100644 (file)
@@ -1,6 +1,5 @@
 use std::collections::hash_map::Entry::{Occupied, Vacant};
 use std::collections::hash_map::HashMap;
-use std::os;
 use std::str;
 use std::sync::Arc;
 
@@ -24,13 +23,12 @@ pub enum Platform {
 }
 
 pub struct Context<'a, 'b: 'a> {
-    pub config: &'b Config<'b>,
+    pub config: &'a Config<'b>,
     pub resolve: &'a Resolve,
-    pub sources: &'a SourceMap<'b>,
+    pub sources: &'a SourceMap<'a>,
     pub compilation: Compilation,
     pub build_state: Arc<BuildState>,
     pub exec_engine: Arc<Box<ExecEngine>>,
-    pub cwd: Path,
 
     env: &'a str,
     host: Layout,
@@ -46,30 +44,29 @@ pub struct Context<'a, 'b: 'a> {
 }
 
 impl<'a, 'b: 'a> Context<'a, 'b> {
-    pub fn new(env: &'a str, resolve: &'a Resolve, sources: &'a SourceMap<'b>,
-               deps: &'a PackageSet, config: &'b Config<'b>,
-               host: Layout, target: Option<Layout>,
+    pub fn new(env: &'a str,
+               resolve: &'a Resolve,
+               sources: &'a SourceMap<'a>,
+               deps: &'a PackageSet,
+               config: &'a Config<'b>,
+               host: Layout,
+               target_layout: Option<Layout>,
                root_pkg: &Package,
-               build_config: BuildConfig)
-               -> CargoResult<Context<'a, 'b>> {
-        let (target_dylib, target_exe) =
-                try!(Context::filename_parts(config.target()));
-        let (host_dylib, host_exe) = if config.target().is_none() {
-            (target_dylib.clone(),
-             target_exe.clone())
+               build_config: BuildConfig) -> CargoResult<Context<'a, 'b>> {
+        let target = build_config.requested_target.clone();
+        let target = target.as_ref().map(|s| &s[]);
+        let (target_dylib, target_exe) = try!(Context::filename_parts(target));
+        let (host_dylib, host_exe) = if build_config.requested_target.is_none() {
+            (target_dylib.clone(), target_exe.clone())
         } else {
             try!(Context::filename_parts(None))
         };
-        let target_triple = config.target().map(|s| s.to_string());
-        let target_triple = target_triple.unwrap_or(config.rustc_host().to_string());
-        let cwd = try!(os::getcwd().chain_error(|| {
-            human("failed to get the current directory")
-        }));
+        let target_triple = target.unwrap_or(config.rustc_host()).to_string();
         Ok(Context {
             target_triple: target_triple,
             env: env,
             host: host,
-            target: target,
+            target: target_layout,
             resolve: resolve,
             sources: sources,
             package_set: deps,
@@ -83,7 +80,6 @@ impl<'a, 'b: 'a> Context<'a, 'b> {
             build_state: Arc::new(BuildState::new(build_config.clone(), deps)),
             build_config: build_config,
             exec_engine: Arc::new(Box::new(ProcessEngine) as Box<ExecEngine>),
-            cwd: cwd,
         })
     }
 
@@ -151,8 +147,9 @@ impl<'a, 'b: 'a> Context<'a, 'b> {
             self.build_requirements(pkg, target, Platform::Target);
         }
 
+        let jobs = self.jobs();
         self.compilation.extra_env.insert("NUM_JOBS".to_string(),
-                                          Some(self.config.jobs().to_string()));
+                                          Some(jobs.to_string()));
         self.compilation.root_output =
                 self.layout(pkg, Kind::Target).proxy().dest().clone();
         self.compilation.deps_output =
@@ -352,6 +349,14 @@ impl<'a, 'b: 'a> Context<'a, 'b> {
             Kind::Target => &self.build_config.target,
         }
     }
+
+    /// Number of jobs specified for this build
+    pub fn jobs(&self) -> u32 { self.build_config.jobs }
+
+    /// Requested (not actual) target for the build
+    pub fn requested_target(&self) -> Option<&str> {
+        self.build_config.requested_target.as_ref().map(|s| &s[])
+    }
 }
 
 impl Platform {
index 87f8c5c6ca3536159baf7d28a500c59ac974dcb3..72560226ae77929d346545718c85ce9c1b408a35 100644 (file)
@@ -57,7 +57,7 @@ pub fn prepare(pkg: &Package, target: &Target, req: Platform,
                  .env("CARGO_MANIFEST_DIR", Some(pkg.get_manifest_path()
                                                     .dir_path()
                                                     .display().to_string()))
-                 .env("NUM_JOBS", Some(cx.config.jobs().to_string()))
+                 .env("NUM_JOBS", Some(cx.jobs().to_string()))
                  .env("TARGET", Some(match kind {
                      Kind::Host => cx.config.rustc_host(),
                      Kind::Target => cx.target_triple(),
index d6f04e88bdd55c1d5a1049b980daa37aff56ddad..bf6a3dc0d15998ae087374bd6c45fafae45e9be6 100644 (file)
@@ -63,11 +63,11 @@ pub enum Stage {
 type Message = (PackageId, Stage, Freshness, CargoResult<()>);
 
 impl<'a, 'b> JobQueue<'a, 'b> {
-    pub fn new(resolve: &'a Resolve, packages: &'a PackageSet,
-               config: &Config) -> JobQueue<'a, 'b> {
+    pub fn new(resolve: &'a Resolve, packages: &'a PackageSet, jobs: u32)
+               -> JobQueue<'a, 'b> {
         let (tx, rx) = channel();
         JobQueue {
-            pool: TaskPool::new(config.jobs() as usize),
+            pool: TaskPool::new(jobs as usize),
             queue: DependencyQueue::new(),
             tx: tx,
             rx: rx,
index c18facd689380db2a5c96188d29a4248f491edc6..95b492634f6a9957fa210f4cd6285fe47d1e7407 100644 (file)
@@ -37,6 +37,8 @@ pub enum Kind { Host, Target }
 pub struct BuildConfig {
     pub host: TargetConfig,
     pub target: TargetConfig,
+    pub jobs: u32,
+    pub requested_target: Option<String>,
 }
 
 #[derive(Clone, Default)]
@@ -113,13 +115,16 @@ fn uniq_target_dest<'a>(targets: &[&'a Target]) -> Option<&'a str> {
 
 // Returns a mapping of the root package plus its immediate dependencies to
 // where the compiled libraries are all located.
-pub fn compile_targets<'a>(env: &str, targets: &[&'a Target], pkg: &'a Package,
-                           deps: &PackageSet, resolve: &'a Resolve,
-                           sources: &'a SourceMap,
-                           config: &'a Config<'a>,
-                           build_config: BuildConfig,
-                           exec_engine: Option<Arc<Box<ExecEngine>>>)
-                           -> CargoResult<Compilation> {
+pub fn compile_targets<'a, 'b>(env: &str,
+                               targets: &[&'a Target],
+                               pkg: &'a Package,
+                               deps: &PackageSet,
+                               resolve: &'a Resolve,
+                               sources: &'a SourceMap<'a>,
+                               config: &'a Config<'b>,
+                               build_config: BuildConfig,
+                               exec_engine: Option<Arc<Box<ExecEngine>>>)
+                               -> CargoResult<Compilation> {
     if targets.is_empty() {
         return Ok(Compilation::new(pkg))
     }
@@ -136,8 +141,8 @@ pub fn compile_targets<'a>(env: &str, targets: &[&'a Target], pkg: &'a Package,
         deps.iter().find(|p| p.get_package_id() == resolve.root()).unwrap()
     };
     let host_layout = Layout::new(root, None, dest);
-    let target_layout = config.target().map(|target| {
-        layout::Layout::new(root, Some(target), dest)
+    let target_layout = build_config.requested_target.as_ref().map(|target| {
+        layout::Layout::new(root, Some(&target[]), dest)
     });
 
     let mut cx = try!(Context::new(env, resolve, sources, deps, config,
@@ -147,7 +152,7 @@ pub fn compile_targets<'a>(env: &str, targets: &[&'a Target], pkg: &'a Package,
         cx.exec_engine = exec_engine.clone();
     }
 
-    let mut queue = JobQueue::new(cx.resolve, deps, cx.config);
+    let mut queue = JobQueue::new(cx.resolve, deps, cx.jobs());
 
     // First ensure that the destination directory exists
     try!(cx.prepare(pkg));
@@ -227,7 +232,7 @@ fn compile<'a, 'b>(targets: &[&'a Target], pkg: &'a Package,
     // Prepare the fingerprint directory as the first step of building a package
     let (target1, target2) = fingerprint::prepare_init(cx, pkg, Kind::Target);
     let mut init = vec![(Job::new(target1, target2), Fresh)];
-    if cx.config.target().is_some() {
+    if cx.requested_target().is_some() {
         let (plugin1, plugin2) = fingerprint::prepare_init(cx, pkg, Kind::Host);
         init.push((Job::new(plugin1, plugin2), Fresh));
     }
@@ -288,7 +293,7 @@ fn compile<'a, 'b>(targets: &[&'a Target], pkg: &'a Package,
             Platform::Target => reqs.push(Platform::Target),
             Platform::Plugin => reqs.push(Platform::Plugin),
             Platform::PluginAndTarget => {
-                if cx.config.target().is_some() {
+                if cx.requested_target().is_some() {
                     reqs.push(Platform::Plugin);
                     reqs.push(Platform::Target);
                 } else {
@@ -489,7 +494,7 @@ fn rustc(package: &Package, target: &Target,
 
         let rustc_dep_info_loc = root.join(target.file_stem()).with_extension("d");
         let dep_info_loc = fingerprint::dep_info_loc(cx, package, target, kind);
-        let cwd = cx.cwd.clone();
+        let cwd = cx.config.cwd().clone();
 
         Ok((Work::new(move |desc_tx| {
             let mut rustc = rustc;
@@ -550,7 +555,7 @@ fn prepare_rustc(package: &Package, target: &Target, crate_types: Vec<&str>,
     Ok(match req {
         Platform::Target => vec![(target_cmd, Kind::Target)],
         Platform::Plugin => vec![(plugin_cmd, Kind::Host)],
-        Platform::PluginAndTarget if cx.config.target().is_none() =>
+        Platform::PluginAndTarget if cx.requested_target().is_none() =>
             vec![(target_cmd, Kind::Target)],
         Platform::PluginAndTarget => vec![(target_cmd, Kind::Target),
                                           (plugin_cmd, Kind::Host)],
@@ -564,7 +569,7 @@ fn rustdoc(package: &Package, target: &Target,
     let cx_root = cx.layout(package, kind).proxy().dest().join("doc");
     let rustdoc = try!(process(CommandType::Rustdoc, package, target, cx));
     let mut rustdoc = rustdoc.arg(root_path(cx, package, target))
-                         .cwd(cx.cwd.clone())
+                         .cwd(cx.config.cwd().clone())
                          .arg("-o").arg(cx_root)
                          .arg("--crate-name").arg(target.get_name());
 
@@ -626,7 +631,7 @@ fn rustdoc(package: &Package, target: &Target,
 // absolute paths instead of relative paths.
 fn root_path(cx: &Context, pkg: &Package, target: &Target) -> Path {
     let absolute = pkg.get_root().join(target.get_src_path());
-    absolute.path_relative_from(&cx.cwd).unwrap_or(absolute)
+    absolute.path_relative_from(cx.config.cwd()).unwrap_or(absolute)
 }
 
 fn build_base_args(cx: &Context,
@@ -637,7 +642,7 @@ fn build_base_args(cx: &Context,
     let metadata = target.get_metadata();
 
     // Move to cwd so the root_path() passed below is actually correct
-    cmd = cmd.cwd(cx.cwd.clone());
+    cmd = cmd.cwd(cx.config.cwd().clone());
 
     // TODO: Handle errors in converting paths into args
     cmd = cmd.arg(root_path(cx, pkg, target));
@@ -735,7 +740,7 @@ fn build_plugin_args(mut cmd: CommandPrototype, cx: &Context, pkg: &Package,
             }
         }
 
-        cmd = opt(cmd, "--target", "", cx.config.target());
+        cmd = opt(cmd, "--target", "", cx.requested_target());
         cmd = opt(cmd, "-C", "ar=", cx.ar(kind));
         cmd = opt(cmd, "-C", "linker=", cx.linker(kind));
     }
index 9d18c03b092890167107f943c295739c4b637dc4..28ca812620f8d72944f21dc1f97800d3e087159c 100644 (file)
@@ -5,19 +5,21 @@ use sources::PathSource;
 use ops::{self, ExecEngine, ProcessEngine};
 use util::{CargoResult, ProcessError};
 
-pub struct TestOptions<'a> {
-    pub compile_opts: ops::CompileOptions<'a>,
+pub struct TestOptions<'a, 'b: 'a> {
+    pub compile_opts: ops::CompileOptions<'a, 'b>,
     pub no_run: bool,
     pub name: Option<&'a str>,
 }
 
 pub fn run_tests(manifest_path: &Path,
-                 options: &mut TestOptions,
+                 options: &TestOptions,
                  test_args: &[String]) -> CargoResult<Option<ProcessError>> {
-    let mut source = try!(PathSource::for_path(&manifest_path.dir_path()));
+    let config = options.compile_opts.config;
+    let mut source = try!(PathSource::for_path(&manifest_path.dir_path(),
+                                               config));
     try!(source.update());
 
-    let mut compile = try!(ops::compile(manifest_path, &mut options.compile_opts));
+    let mut compile = try!(ops::compile(manifest_path, &options.compile_opts));
     if options.no_run { return Ok(None) }
     compile.tests.sort();
 
@@ -34,10 +36,10 @@ pub fn run_tests(manifest_path: &Path,
         };
         let cmd = try!(compile.target_process(exe, &compile.package))
                   .args(test_args);
-        try!(options.compile_opts.shell.concise(|shell| {
+        try!(config.shell().concise(|shell| {
             shell.status("Running", to_display.display().to_string())
         }));
-        try!(options.compile_opts.shell.verbose(|shell| {
+        try!(config.shell().verbose(|shell| {
             shell.status("Running", cmd.to_string())
         }));
         match ExecEngine::exec(&mut ProcessEngine, cmd) {
@@ -58,7 +60,7 @@ pub fn run_tests(manifest_path: &Path,
     });
 
     for (lib, name) in libs {
-        try!(options.compile_opts.shell.status("Doc-tests", name));
+        try!(config.shell().status("Doc-tests", name));
         let mut p = try!(compile.rustdoc_process(&compile.package))
                            .arg("--test").arg(lib)
                            .arg("--crate-name").arg(name)
@@ -80,7 +82,7 @@ pub fn run_tests(manifest_path: &Path,
             }
         }
 
-        try!(options.compile_opts.shell.verbose(|shell| {
+        try!(config.shell().verbose(|shell| {
             shell.status("Running", p.to_string())
         }));
         match ExecEngine::exec(&mut ProcessEngine, p) {
@@ -93,7 +95,7 @@ pub fn run_tests(manifest_path: &Path,
 }
 
 pub fn run_benches(manifest_path: &Path,
-                   options: &mut TestOptions,
+                   options: &TestOptions,
                    args: &[String]) -> CargoResult<Option<ProcessError>> {
     let mut args = args.to_vec();
     args.push("--bench".to_string());
index d023c83c5e010ebd0c69ab355b29f9878c022de6..28b636f37418d939318c5b64236e7f4fb2ef5867 100644 (file)
@@ -10,7 +10,7 @@ use registry::{Registry, NewCrate, NewCrateDependency};
 use term::color::BLACK;
 
 use core::source::Source;
-use core::{Package, MultiShell, SourceId};
+use core::{Package, SourceId};
 use core::dependency::Kind;
 use core::manifest::ManifestMetadata;
 use ops;
@@ -26,23 +26,25 @@ pub struct RegistryConfig {
 }
 
 pub fn publish(manifest_path: &Path,
-               shell: &mut MultiShell,
+               config: &Config,
                token: Option<String>,
                index: Option<String>,
                verify: bool) -> CargoResult<()> {
-    let mut src = try!(PathSource::for_path(&manifest_path.dir_path()));
+    let mut src = try!(PathSource::for_path(&manifest_path.dir_path(),
+                                            config));
     try!(src.update());
     let pkg = try!(src.get_root_package());
 
-    let (mut registry, reg_id) = try!(registry(shell, token, index));
+    let (mut registry, reg_id) = try!(registry(config, token, index));
     try!(verify_dependencies(&pkg, &reg_id));
 
     // Prepare a tarball, with a non-surpressable warning if metadata
     // is missing since this is being put online.
-    let tarball = try!(ops::package(manifest_path, shell, verify, false, true)).unwrap();
+    let tarball = try!(ops::package(manifest_path, config, verify,
+                                    false, true)).unwrap();
 
     // Upload said tarball to the specified destination
-    try!(shell.status("Uploading", pkg.get_package_id().to_string()));
+    try!(config.shell().status("Uploading", pkg.get_package_id().to_string()));
     try!(transmit(&pkg, &tarball, &mut registry));
 
     Ok(())
@@ -128,8 +130,8 @@ fn transmit(pkg: &Package, tarball: &Path, registry: &mut Registry)
     })
 }
 
-pub fn registry_configuration() -> CargoResult<RegistryConfig> {
-    let configs = try!(config::all_configs(try!(os::getcwd())));
+pub fn registry_configuration(config: &Config) -> CargoResult<RegistryConfig> {
+    let configs = try!(config.values());
     let registry = match configs.get("registry") {
         None => return Ok(RegistryConfig { index: None, token: None }),
         Some(registry) => try!(registry.table().chain_error(|| {
@@ -155,33 +157,32 @@ pub fn registry_configuration() -> CargoResult<RegistryConfig> {
     Ok(RegistryConfig { index: index, token: token })
 }
 
-pub fn registry(shell: &mut MultiShell,
+pub fn registry(config: &Config,
                 token: Option<String>,
                 index: Option<String>) -> CargoResult<(Registry, SourceId)> {
     // Parse all configuration options
     let RegistryConfig {
         token: token_config,
         index: index_config,
-    } = try!(registry_configuration());
+    } = try!(registry_configuration(config));
     let token = token.or(token_config);
     let index = index.or(index_config).unwrap_or(RegistrySource::default_url());
     let index = try!(index.as_slice().to_url().map_err(human));
     let sid = SourceId::for_registry(&index);
     let api_host = {
-        let mut config = try!(Config::new(shell, None, None));
-        let mut src = RegistrySource::new(&sid, &mut config);
+        let mut src = RegistrySource::new(&sid, config);
         try!(src.update().chain_error(|| {
             human(format!("Failed to update registry {}", index))
         }));
         (try!(src.config())).api
     };
-    let handle = try!(http_handle());
+    let handle = try!(http_handle(config));
     Ok((Registry::new_handle(api_host, token, handle), sid))
 }
 
 /// Create a new HTTP handle with appropriate global configuration for cargo.
-pub fn http_handle() -> CargoResult<http::Handle> {
-    Ok(match try!(http_proxy()) {
+pub fn http_handle(config: &Config) -> CargoResult<http::Handle> {
+    Ok(match try!(http_proxy(config)) {
         Some(proxy) => http::handle().proxy(proxy),
         None => http::handle(),
     })
@@ -191,8 +192,8 @@ pub fn http_handle() -> CargoResult<http::Handle> {
 ///
 /// Favor cargo's `http.proxy`, then git's `http.proxy`, then finally a
 /// HTTP_PROXY env var.
-pub fn http_proxy() -> CargoResult<Option<String>> {
-    let configs = try!(config::all_configs(try!(os::getcwd())));
+pub fn http_proxy(config: &Config) -> CargoResult<Option<String>> {
+    let configs = try!(config.values());
     match configs.get("http") {
         Some(http) => {
             let http = try!(http.table().chain_error(|| {
@@ -221,9 +222,8 @@ pub fn http_proxy() -> CargoResult<Option<String>> {
     Ok(os::getenv("HTTP_PROXY"))
 }
 
-pub fn registry_login(shell: &mut MultiShell, token: String) -> CargoResult<()> {
-    let config = try!(Config::new(shell, None, None));
-    let RegistryConfig { index, token: _ } = try!(registry_configuration());
+pub fn registry_login(config: &Config, token: String) -> CargoResult<()> {
+    let RegistryConfig { index, token: _ } = try!(registry_configuration(config));
     let mut map = HashMap::new();
     let p = try!(os::getcwd());
     match index {
@@ -234,7 +234,7 @@ pub fn registry_login(shell: &mut MultiShell, token: String) -> CargoResult<()>
     }
     map.insert("token".to_string(), ConfigValue::String(token, p));
 
-    config::set_config(&config, Location::Global, "registry",
+    config::set_config(config, Location::Global, "registry",
                        ConfigValue::Table(map))
 }
 
@@ -247,26 +247,27 @@ pub struct OwnersOptions {
     pub list: bool,
 }
 
-pub fn modify_owners(shell: &mut MultiShell,
-                     opts: &OwnersOptions) -> CargoResult<()> {
+pub fn modify_owners(config: &Config, opts: &OwnersOptions) -> CargoResult<()> {
     let name = match opts.krate {
         Some(ref name) => name.clone(),
         None => {
             let manifest_path = try!(find_root_manifest_for_cwd(None));
-            let mut src = try!(PathSource::for_path(&manifest_path.dir_path()));
+            let mut src = try!(PathSource::for_path(&manifest_path.dir_path(),
+                                                    config));
             try!(src.update());
             let pkg = try!(src.get_root_package());
             pkg.get_name().to_string()
         }
     };
 
-    let (mut registry, _) = try!(registry(shell, opts.token.clone(),
+    let (mut registry, _) = try!(registry(config, opts.token.clone(),
                                           opts.index.clone()));
 
     match opts.to_add {
         Some(ref v) => {
             let v = v.iter().map(|s| s.as_slice()).collect::<Vec<_>>();
-            try!(shell.status("Owner", format!("adding `{:#?}` to `{}`", v, name)));
+            try!(config.shell().status("Owner", format!("adding `{:#?}` to `{}`",
+                                                        v, name)));
             try!(registry.add_owners(name.as_slice(), v.as_slice()).map_err(|e| {
                 human(format!("failed to add owners: {}", e))
             }));
@@ -277,8 +278,8 @@ pub fn modify_owners(shell: &mut MultiShell,
     match opts.to_remove {
         Some(ref v) => {
             let v = v.iter().map(|s| s.as_slice()).collect::<Vec<_>>();
-            try!(shell.status("Owner", format!("removing `{:?}` from `{}`",
-                                               v, name)));
+            try!(config.shell().status("Owner", format!("removing `{:?}` from `{}`",
+                                                        v, name)));
             try!(registry.remove_owners(name.as_slice(), v.as_slice()).map_err(|e| {
                 human(format!("failed to add owners: {}", e))
             }));
@@ -304,7 +305,7 @@ pub fn modify_owners(shell: &mut MultiShell,
     Ok(())
 }
 
-pub fn yank(shell: &mut MultiShell,
+pub fn yank(config: &Config,
             krate: Option<String>,
             version: Option<String>,
             token: Option<String>,
@@ -314,7 +315,8 @@ pub fn yank(shell: &mut MultiShell,
         Some(name) => name,
         None => {
             let manifest_path = try!(find_root_manifest_for_cwd(None));
-            let mut src = try!(PathSource::for_path(&manifest_path.dir_path()));
+            let mut src = try!(PathSource::for_path(&manifest_path.dir_path(),
+                                                    config));
             try!(src.update());
             let pkg = try!(src.get_root_package());
             pkg.get_name().to_string()
@@ -325,15 +327,15 @@ pub fn yank(shell: &mut MultiShell,
         None => return Err(human("a version must be specified to yank"))
     };
 
-    let (mut registry, _) = try!(registry(shell, token, index));
+    let (mut registry, _) = try!(registry(config, token, index));
 
     if undo {
-        try!(shell.status("Unyank", format!("{}:{}", name, version)));
+        try!(config.shell().status("Unyank", format!("{}:{}", name, version)));
         try!(registry.unyank(name.as_slice(), version.as_slice()).map_err(|e| {
             human(format!("failed to undo a yank: {}", e))
         }));
     } else {
-        try!(shell.status("Yank", format!("{}:{}", name, version)));
+        try!(config.shell().status("Yank", format!("{}:{}", name, version)));
         try!(registry.yank(name.as_slice(), version.as_slice()).map_err(|e| {
             human(format!("failed to yank: {}", e))
         }));
@@ -342,7 +344,7 @@ pub fn yank(shell: &mut MultiShell,
     Ok(())
 }
 
-pub fn search(query: &str, shell: &mut MultiShell, index: Option<String>) -> CargoResult<()> {
+pub fn search(query: &str, config: &Config, index: Option<String>) -> CargoResult<()> {
     fn truncate_with_ellipsis(s: &str, max_length: usize) -> String {
         if s.len() < max_length {
             s.to_string()
@@ -351,8 +353,7 @@ pub fn search(query: &str, shell: &mut MultiShell, index: Option<String>) -> Car
         }
     }
 
-    let (mut registry, _) = try!(registry(shell, None, index));
-
+    let (mut registry, _) = try!(registry(config, None, index));
     let crates = try!(registry.search(query).map_err(|e| {
         human(format!("failed to retrieve search results from the registry: {}", e))
     }));
@@ -378,7 +379,7 @@ pub fn search(query: &str, shell: &mut MultiShell, index: Option<String>) -> Car
             }
             None => name
         };
-        try!(shell.say(line, BLACK));
+        try!(config.shell().say(line, BLACK));
     }
 
     Ok(())
index e649843b9d384177f189914ecced276a3cc7ad14..e6ae188df425b0b749b7c13dd24bfd9c41e3c9f7 100644 (file)
@@ -18,7 +18,7 @@ pub struct GitSource<'a, 'b:'a> {
     db_path: Path,
     checkout_path: Path,
     source_id: SourceId,
-    path_source: Option<PathSource>,
+    path_source: Option<PathSource<'a, 'b>>,
     rev: Option<GitRevision>,
     config: &'a Config<'b>,
 }
@@ -183,7 +183,8 @@ impl<'a, 'b> Source for GitSource<'a, 'b> {
         try!(repo.copy_to(actual_rev.clone(), &self.checkout_path));
 
         let source_id = self.source_id.with_precise(Some(actual_rev.to_string()));
-        let path_source = PathSource::new(&self.checkout_path, &source_id);
+        let path_source = PathSource::new(&self.checkout_path, &source_id,
+                                          self.config);
 
         self.path_source = Some(path_source);
         self.rev = Some(actual_rev);
index c1278c18e1fd67b15331a92885ed203bfcbca60a..569188c266139d92925a3356019aa5e58979e82d 100644 (file)
@@ -6,35 +6,38 @@ use git2;
 
 use core::{Package, PackageId, Summary, SourceId, Source, Dependency, Registry};
 use ops;
-use util::{CargoResult, internal, internal_error, human, ChainError};
+use util::{CargoResult, internal, internal_error, human, ChainError, Config};
 
-pub struct PathSource {
+pub struct PathSource<'a, 'b: 'a> {
     id: SourceId,
     path: Path,
     updated: bool,
-    packages: Vec<Package>
+    packages: Vec<Package>,
+    config: &'a Config<'b>,
 }
 
 // TODO: Figure out if packages should be discovered in new or self should be
 // mut and packages are discovered in update
-impl PathSource {
-
-    pub fn for_path(path: &Path) -> CargoResult<PathSource> {
+impl<'a, 'b> PathSource<'a, 'b> {
+    pub fn for_path(path: &Path, config: &'a Config<'b>)
+                    -> CargoResult<PathSource<'a, 'b>> {
         log!(5, "PathSource::for_path; path={}", path.display());
-        Ok(PathSource::new(path, &try!(SourceId::for_path(path))))
+        Ok(PathSource::new(path, &try!(SourceId::for_path(path)), config))
     }
 
     /// Invoked with an absolute path to a directory that contains a Cargo.toml.
     /// The source will read the manifest and find any other packages contained
     /// in the directory structure reachable by the root manifest.
-    pub fn new(path: &Path, id: &SourceId) -> PathSource {
+    pub fn new(path: &Path, id: &SourceId, config: &'a Config<'b>)
+               -> PathSource<'a, 'b> {
         log!(5, "new; id={}", id);
 
         PathSource {
             id: id.clone(),
             path: path.clone(),
             updated: false,
-            packages: Vec::new()
+            packages: Vec::new(),
+            config: config,
         }
     }
 
@@ -55,7 +58,7 @@ impl PathSource {
         if self.updated {
             Ok(self.packages.clone())
         } else {
-            ops::read_packages(&self.path, &self.id)
+            ops::read_packages(&self.path, &self.id, self.config)
         }
     }
 
@@ -198,13 +201,13 @@ impl PathSource {
     }
 }
 
-impl Show for PathSource {
+impl<'a, 'b> Show for PathSource<'a, 'b> {
     fn fmt(&self, f: &mut Formatter) -> fmt::Result {
         write!(f, "the paths source")
     }
 }
 
-impl Registry for PathSource {
+impl<'a, 'b> Registry for PathSource<'a, 'b> {
     fn query(&mut self, dep: &Dependency) -> CargoResult<Vec<Summary>> {
         let mut summaries: Vec<Summary> = self.packages.iter()
                                               .map(|p| p.get_summary().clone())
@@ -213,7 +216,7 @@ impl Registry for PathSource {
     }
 }
 
-impl Source for PathSource {
+impl<'a, 'b> Source for PathSource<'a, 'b> {
     fn update(&mut self) -> CargoResult<()> {
         if !self.updated {
             let packages = try!(self.read_packages());
index 0c40ee4ccc7fe641d258edb2882dd204c3ed3bf1..392d5e78ffff729b5767a714ef8861aa438c5e49 100644 (file)
@@ -186,7 +186,7 @@ pub struct RegistrySource<'a, 'b:'a> {
     src_path: Path,
     config: &'a Config<'b>,
     handle: Option<http::Handle>,
-    sources: Vec<PathSource>,
+    sources: Vec<PathSource<'a, 'b>>,
     hashes: HashMap<(String, String), String>, // (name, vers) => cksum
     cache: HashMap<String, Vec<(Summary, bool)>>,
     updated: bool,
@@ -249,8 +249,8 @@ impl<'a, 'b> RegistrySource<'a, 'b> {
     ///
     /// This is the main cargo registry by default, but it can be overridden in
     /// a .cargo/config
-    pub fn url() -> CargoResult<Url> {
-        let config = try!(ops::registry_configuration());
+    pub fn url(config: &Config) -> CargoResult<Url> {
+        let config = try!(ops::registry_configuration(config));
         let url = config.index.unwrap_or(DEFAULT.to_string());
         url.as_slice().to_url().map_err(human)
     }
@@ -306,7 +306,7 @@ impl<'a, 'b> RegistrySource<'a, 'b> {
         let handle = match self.handle {
             Some(ref mut handle) => handle,
             None => {
-                self.handle = Some(try!(ops::http_handle()));
+                self.handle = Some(try!(ops::http_handle(self.config)));
                 self.handle.as_mut().unwrap()
             }
         };
@@ -511,7 +511,7 @@ impl<'a, 'b> Source for RegistrySource<'a, 'b> {
             let path = try!(self.unpack_package(package, path).chain_error(|| {
                 internal(format!("Failed to unpack package `{}`", package))
             }));
-            let mut src = PathSource::new(&path, &self.source_id);
+            let mut src = PathSource::new(&path, &self.source_id, self.config);
             try!(src.update());
             self.sources.push(src);
         }
index e80cc23cce28126835f9ce030a33c6b92b05f97d..544eff51f54427b94ab0a7fd30e697d96c462575 100644 (file)
@@ -1,10 +1,9 @@
 use std::{fmt, os, mem};
-use std::cell::{RefCell, RefMut};
+use std::cell::{RefCell, RefMut, Ref, Cell};
 use std::collections::hash_map::{HashMap};
 use std::collections::hash_map::Entry::{Occupied, Vacant};
 use std::io;
 use std::io::fs::{self, PathExtensions, File};
-use std::string;
 
 use rustc_serialize::{Encodable,Encoder};
 use toml;
@@ -19,21 +18,19 @@ use self::ConfigValue as CV;
 pub struct Config<'a> {
     home_path: Path,
     shell: RefCell<&'a mut MultiShell>,
-    jobs: u32,
-    target: Option<string::String>,
-    rustc_version: string::String,
+    rustc_version: String,
     /// The current host and default target of rustc
-    rustc_host: string::String,
+    rustc_host: String,
+    values: RefCell<HashMap<String, ConfigValue>>,
+    values_loaded: Cell<bool>,
+    cwd: Path,
 }
 
 impl<'a> Config<'a> {
-    pub fn new(shell: &'a mut MultiShell,
-               jobs: Option<u32>,
-               target: Option<string::String>) -> CargoResult<Config<'a>> {
-        if jobs == Some(0) {
-            return Err(human("jobs must be at least 1"))
-        }
-
+    pub fn new(shell: &'a mut MultiShell) -> CargoResult<Config<'a>> {
+        let cwd = try!(os::getcwd().chain_error(|| {
+            human("couldn't get the current directory of the process")
+        }));
         let (rustc_version, rustc_host) = try!(ops::rustc_version());
 
         Ok(Config {
@@ -42,10 +39,11 @@ impl<'a> Config<'a> {
                       This probably means that $HOME was not set.")
             })),
             shell: RefCell::new(shell),
-            jobs: jobs.unwrap_or(os::num_cpus() as u32),
-            target: target,
             rustc_version: rustc_version,
             rustc_host: rustc_host,
+            cwd: cwd,
+            values: RefCell::new(HashMap::new()),
+            values_loaded: Cell::new(false),
         })
     }
 
@@ -75,14 +73,6 @@ impl<'a> Config<'a> {
         self.shell.borrow_mut()
     }
 
-    pub fn jobs(&self) -> u32 {
-        self.jobs
-    }
-
-    pub fn target(&self) -> Option<&str> {
-        self.target.as_ref().map(|t| t.as_slice())
-    }
-
     /// Return the output of `rustc -v verbose`
     pub fn rustc_version(&self) -> &str {
         self.rustc_version.as_slice()
@@ -92,6 +82,21 @@ impl<'a> Config<'a> {
     pub fn rustc_host(&self) -> &str {
         self.rustc_host.as_slice()
     }
+
+    pub fn values(&self) -> CargoResult<Ref<HashMap<String, ConfigValue>>> {
+        if !self.values_loaded.get() {
+            try!(self.load_values());
+            self.values_loaded.set(true);
+        }
+        Ok(self.values.borrow())
+    }
+
+    pub fn cwd(&self) -> &Path { &self.cwd }
+
+    fn load_values(&self) -> CargoResult<()> {
+        *self.values.borrow_mut() = try!(all_configs(&self.cwd));
+        Ok(())
+    }
 }
 
 #[derive(Eq, PartialEq, Clone, RustcEncodable, RustcDecodable, Copy)]
@@ -102,9 +107,9 @@ pub enum Location {
 
 #[derive(Eq,PartialEq,Clone,RustcDecodable)]
 pub enum ConfigValue {
-    String(string::String, Path),
-    List(Vec<(string::String, Path)>),
-    Table(HashMap<string::String, ConfigValue>),
+    String(String, Path),
+    List(Vec<(String, Path)>),
+    Table(HashMap<String, ConfigValue>),
     Boolean(bool, Path),
 }
 
@@ -135,7 +140,7 @@ impl Encodable for ConfigValue {
         match *self {
             CV::String(ref string, _) => string.encode(s),
             CV::List(ref list) => {
-                let list: Vec<&string::String> = list.iter().map(|s| &s.0).collect();
+                let list: Vec<&String> = list.iter().map(|s| &s.0).collect();
                 list.encode(s)
             }
             CV::Table(ref table) => table.encode(s),
@@ -201,7 +206,7 @@ impl ConfigValue {
         }
     }
 
-    pub fn table(&self) -> CargoResult<&HashMap<string::String, ConfigValue>> {
+    pub fn table(&self) -> CargoResult<&HashMap<String, ConfigValue>> {
         match *self {
             CV::Table(ref table) => Ok(table),
             _ => Err(internal(format!("expected a table, but found a {}",
@@ -209,7 +214,7 @@ impl ConfigValue {
         }
     }
 
-    pub fn list(&self) -> CargoResult<&[(string::String, Path)]> {
+    pub fn list(&self) -> CargoResult<&[(String, Path)]> {
         match *self {
             CV::List(ref list) => Ok(list.as_slice()),
             _ => Err(internal(format!("expected a list, but found a {}",
@@ -260,10 +265,10 @@ pub fn get_config(pwd: Path, key: &str) -> CargoResult<ConfigValue> {
         human(format!("`{}` not found in your configuration", key)))
 }
 
-pub fn all_configs(pwd: Path) -> CargoResult<HashMap<string::String, ConfigValue>> {
+pub fn all_configs(pwd: &Path) -> CargoResult<HashMap<String, ConfigValue>> {
     let mut cfg = CV::Table(HashMap::new());
 
-    try!(walk_tree(&pwd, |mut file| {
+    try!(walk_tree(pwd, |mut file| {
         let path = file.path().clone();
         let contents = try!(file.read_to_string());
         let table = try!(cargo_toml::parse(contents.as_slice(), &path).chain_error(|| {
index 447ee174e6c17798f5cde4d731afcf1795f4234b..b7321d46e4bd6e054a4db2ba8a274f6f42b15785 100644 (file)
@@ -15,7 +15,7 @@ use core::{Summary, Manifest, Target, Dependency, PackageId, GitReference};
 use core::dependency::Kind;
 use core::manifest::{LibKind, Profile, ManifestMetadata};
 use core::package_id::Metadata;
-use util::{CargoResult, human, ToUrl, ToSemver, ChainError};
+use util::{CargoResult, human, ToUrl, ToSemver, ChainError, Config};
 
 /// Representation of the projects file layout.
 ///
@@ -91,7 +91,8 @@ pub fn project_layout(root_path: &Path) -> Layout {
 
 pub fn to_manifest(contents: &[u8],
                    source_id: &SourceId,
-                   layout: Layout)
+                   layout: Layout,
+                   config: &Config)
                    -> CargoResult<(Manifest, Vec<Path>)> {
     let manifest = layout.root.join("Cargo.toml");
     let manifest = match manifest.path_relative_from(&try!(os::getcwd())) {
@@ -110,7 +111,7 @@ pub fn to_manifest(contents: &[u8],
                                            manifest.display(), e)))
     };
 
-    let pair = try!(toml_manifest.to_manifest(source_id, &layout).map_err(|err| {
+    let pair = try!(toml_manifest.to_manifest(source_id, &layout, config).map_err(|err| {
         human(format!("{} is not a valid manifest\n\n{}",
                       manifest.display(), err))
     }));
@@ -302,10 +303,11 @@ impl TomlProject {
     }
 }
 
-struct Context<'a> {
+struct Context<'a, 'b, 'c: 'b> {
     deps: &'a mut Vec<Dependency>,
     source_id: &'a SourceId,
-    nested_paths: &'a mut Vec<Path>
+    nested_paths: &'a mut Vec<Path>,
+    config: &'b Config<'c>,
 }
 
 // These functions produce the equivalent of specific manifest entries. One
@@ -380,7 +382,8 @@ fn inferred_bench_targets(layout: &Layout) -> Vec<TomlTarget> {
 }
 
 impl TomlManifest {
-    pub fn to_manifest(&self, source_id: &SourceId, layout: &Layout)
+    pub fn to_manifest(&self, source_id: &SourceId, layout: &Layout,
+                       config: &Config)
         -> CargoResult<(Manifest, Vec<Path>)> {
         let mut nested_paths = vec!();
 
@@ -486,7 +489,8 @@ impl TomlManifest {
             let mut cx = Context {
                 deps: &mut deps,
                 source_id: source_id,
-                nested_paths: &mut nested_paths
+                nested_paths: &mut nested_paths,
+                config: config,
             };
 
             // Collect the deps
@@ -593,7 +597,7 @@ fn process_dependencies<F>(cx: &mut Context,
                     cx.source_id.clone()
                 })
             }
-        }.unwrap_or(try!(SourceId::for_central()));
+        }.unwrap_or(try!(SourceId::for_central(cx.config)));
 
         let dep = try!(Dependency::parse(n.as_slice(),
                                          details.version.as_ref()
index b24dc6077c5eceb832cf90acf5ae068d4823d5f3..618ad281d4d3644bcd5d9aba89a8e4b39feca6da 100644 (file)
@@ -1,4 +1,4 @@
-use std::io::fs::{self, PathExtensions};
+use std::io::fs;
 use std::io;
 use std::io::{USER_RWX, File};
 use std::os;
@@ -23,14 +23,9 @@ fn fake_executable(proj: ProjectBuilder, dir: &Path, name: &str) -> ProjectBuild
     proj
 }
 
-// We can't entirely obliterate PATH because windows needs it for paths to
-// things like libgcc, but we want to filter out everything which has a `cargo`
-// installation as we don't want it to muck with the --list tests
-fn new_path() -> Vec<Path> {
+fn path() -> Vec<Path> {
     let path = os::getenv_as_bytes("PATH").unwrap_or(Vec::new());
-    os::split_paths(path).into_iter().filter(|p| {
-        !p.join(format!("cargo{}", os::consts::EXE_SUFFIX)).exists()
-    }).collect()
+    os::split_paths(path)
 }
 test!(list_commands_looks_at_path {
     let proj = project("list-non-overlapping");
@@ -40,7 +35,7 @@ test!(list_commands_looks_at_path {
         .cwd(proj.root())
         .env("HOME", Some(paths::home()));
 
-    let mut path = new_path();
+    let mut path = path();
     path.push(proj.root().join("path-test"));
     let path = os::join_paths(path.as_slice()).unwrap();
     let output = pr.arg("-v").arg("--list").env("PATH", Some(path.as_slice()));
index b6ab7cdb927cea0ce23e771491a4bc462f4c5ed8..018f45b39352cc7f7715674c43637cb6b26725b1 100644 (file)
@@ -703,19 +703,22 @@ test!(update_with_shared_deps {
 
     // By default, not transitive updates
     println!("dep1 update");
-    assert_that(p.process(cargo_dir().join("cargo")).arg("update").arg("dep1"),
+    assert_that(p.process(cargo_dir().join("cargo")).arg("update")
+                 .arg("-p").arg("dep1"),
                 execs().with_stdout(""));
 
     // Specifying a precise rev to the old rev shouldn't actually update
     // anything because we already have the rev in the db.
     println!("bar precise update");
-    assert_that(p.process(cargo_dir().join("cargo")).arg("update").arg("bar")
+    assert_that(p.process(cargo_dir().join("cargo")).arg("update")
+                 .arg("-p").arg("bar")
                  .arg("--precise").arg(old_head.to_string()),
                 execs().with_stdout(""));
 
     // Updating aggressively should, however, update the repo.
     println!("dep1 aggressive update");
-    assert_that(p.process(cargo_dir().join("cargo")).arg("update").arg("dep1")
+    assert_that(p.process(cargo_dir().join("cargo")).arg("update")
+                 .arg("-p").arg("dep1")
                  .arg("--aggressive"),
                 execs().with_stdout(format!("{} git repository `{}`",
                                             UPDATING,
@@ -733,7 +736,8 @@ test!(update_with_shared_deps {
                     compiling = COMPILING, dir = p.url())));
 
     // We should be able to update transitive deps
-    assert_that(p.process(cargo_dir().join("cargo")).arg("update").arg("bar"),
+    assert_that(p.process(cargo_dir().join("cargo")).arg("update")
+                 .arg("-p").arg("bar"),
                 execs().with_stdout(format!("{} git repository `{}`",
                                             UPDATING,
                                             git_project.url())));